Skip to content

Commit 312fcd0

Browse files
author
Nick Kledzik
committed
libcxxabi contains the runtime support for C++. But, as some folks have realized, it is not complete. It relies on some _Unwind_* functions to be supplied by the OS. That means it cannot be ported to platforms that don’t already have an unwinder. Years ago Apple wrote its own unwinder for MacOSX and iOS. To make libcxxabi complete, Apple has decided the source code for its unwinder can be contributed to the open source LLVM libcxxabi project, with a dual licensed under LLVM and MIT license. So, I’ve spent some time cleaning up the sources to make them conform with LLVM style and to conditionalize the sources in a way that should make it easier to port to other platforms. The sources are in a separate "Unwind" directory under "src" in libcxxabi. Background: Most architectures now use "zero cost" exceptions for C++. The zero cost means there are no extra instructions executed if no exceptions are thrown. But if an exception is thrown, the runtime must consult side tables and figure out how to restore registers and "unwind" from the current stack frame to the catch clause. That ability to modify the stack frames and cause the thread to resume in a catch clause with all registers restored properly is the main purpose of the unwinder. This unwinder has two levels of API. The high level APIs are the _Unwind_* functions which the cxa_* exception functions in libcxxabi require. The low level APIs are the unw_* functions which are an interface defined by the the old HP libunwind project (which shares no code with this unwinder). llvm-svn: 192136
1 parent 57a2d2f commit 312fcd0

20 files changed

+8889
-0
lines changed

libcxxabi/include/libunwind.h

Lines changed: 356 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,356 @@
1+
//===---------------------------- libunwind.h -----------------------------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is dual licensed under the MIT and the University of Illinois Open
6+
// Source Licenses. See LICENSE.TXT for details.
7+
//
8+
//
9+
// Compatible with libuwind API documented at:
10+
// http://www.nongnu.org/libunwind/man/libunwind(3).html
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef __LIBUNWIND__
15+
#define __LIBUNWIND__
16+
17+
#include <stdint.h>
18+
#include <stddef.h>
19+
20+
#if __APPLE__
21+
#include <Availability.h>
22+
#if __arm__
23+
#define LIBUNWIND_AVAIL __attribute__((unavailable))
24+
#else
25+
#define LIBUNWIND_AVAIL __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_5_0)
26+
#endif
27+
#else
28+
#define LIBUNWIND_AVAIL
29+
#endif
30+
31+
/* error codes */
32+
enum {
33+
UNW_ESUCCESS = 0, /* no error */
34+
UNW_EUNSPEC = -6540, /* unspecified (general) error */
35+
UNW_ENOMEM = -6541, /* out of memory */
36+
UNW_EBADREG = -6542, /* bad register number */
37+
UNW_EREADONLYREG = -6543, /* attempt to write read-only register */
38+
UNW_ESTOPUNWIND = -6544, /* stop unwinding */
39+
UNW_EINVALIDIP = -6545, /* invalid IP */
40+
UNW_EBADFRAME = -6546, /* bad frame */
41+
UNW_EINVAL = -6547, /* unsupported operation or bad value */
42+
UNW_EBADVERSION = -6548, /* unwind info has unsupported version */
43+
UNW_ENOINFO = -6549 /* no unwind info found */
44+
};
45+
46+
struct unw_context_t {
47+
uint64_t data[128];
48+
};
49+
typedef struct unw_context_t unw_context_t;
50+
51+
struct unw_cursor_t {
52+
uint64_t data[140];
53+
};
54+
typedef struct unw_cursor_t unw_cursor_t;
55+
56+
typedef struct unw_addr_space *unw_addr_space_t;
57+
58+
typedef int unw_regnum_t;
59+
typedef uint64_t unw_word_t;
60+
typedef double unw_fpreg_t;
61+
62+
struct unw_proc_info_t {
63+
unw_word_t start_ip; /* start address of function */
64+
unw_word_t end_ip; /* address after end of function */
65+
unw_word_t lsda; /* address of language specific data area, */
66+
/* or zero if not used */
67+
unw_word_t handler; /* personality routine, or zero if not used */
68+
unw_word_t gp; /* not used */
69+
unw_word_t flags; /* not used */
70+
uint32_t format; /* compact unwind encoding, or zero if none */
71+
uint32_t unwind_info_size; /* size of dwarf unwind info, or zero if none */
72+
unw_word_t unwind_info; /* address of dwarf unwind info, or zero */
73+
unw_word_t extra; /* mach_header of mach-o image containing func */
74+
};
75+
typedef struct unw_proc_info_t unw_proc_info_t;
76+
77+
#ifdef __cplusplus
78+
extern "C" {
79+
#endif
80+
81+
extern int unw_getcontext(unw_context_t *) LIBUNWIND_AVAIL;
82+
extern int unw_init_local(unw_cursor_t *, unw_context_t *) LIBUNWIND_AVAIL;
83+
extern int unw_step(unw_cursor_t *) LIBUNWIND_AVAIL;
84+
extern int unw_get_reg(unw_cursor_t *, unw_regnum_t, unw_word_t *) LIBUNWIND_AVAIL;
85+
extern int unw_get_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t *) LIBUNWIND_AVAIL;
86+
extern int unw_set_reg(unw_cursor_t *, unw_regnum_t, unw_word_t) LIBUNWIND_AVAIL;
87+
extern int unw_set_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t) LIBUNWIND_AVAIL;
88+
extern int unw_resume(unw_cursor_t *) LIBUNWIND_AVAIL;
89+
90+
extern const char *unw_regname(unw_cursor_t *, unw_regnum_t) LIBUNWIND_AVAIL;
91+
extern int unw_get_proc_info(unw_cursor_t *, unw_proc_info_t *) LIBUNWIND_AVAIL;
92+
extern int unw_is_fpreg(unw_cursor_t *, unw_regnum_t) LIBUNWIND_AVAIL;
93+
extern int unw_is_signal_frame(unw_cursor_t *) LIBUNWIND_AVAIL;
94+
extern int unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *) LIBUNWIND_AVAIL;
95+
//extern int unw_get_save_loc(unw_cursor_t*, int, unw_save_loc_t*);
96+
97+
#if UNW_REMOTE
98+
/*
99+
* Mac OS X "remote" API for unwinding other processes on same machine
100+
*
101+
*/
102+
extern unw_addr_space_t unw_local_addr_space;
103+
extern unw_addr_space_t unw_create_addr_space_for_task(task_t);
104+
extern void unw_destroy_addr_space(unw_addr_space_t);
105+
extern int unw_init_remote_thread(unw_cursor_t *, unw_addr_space_t, thread_t *);
106+
#endif
107+
108+
/*
109+
* traditional libuwind "remote" API
110+
* NOT IMPLEMENTED on Mac OS X
111+
*
112+
* extern int unw_init_remote(unw_cursor_t*, unw_addr_space_t,
113+
* thread_t*);
114+
* extern unw_accessors_t unw_get_accessors(unw_addr_space_t);
115+
* extern unw_addr_space_t unw_create_addr_space(unw_accessors_t, int);
116+
* extern void unw_flush_cache(unw_addr_space_t, unw_word_t,
117+
* unw_word_t);
118+
* extern int unw_set_caching_policy(unw_addr_space_t,
119+
* unw_caching_policy_t);
120+
* extern void _U_dyn_register(unw_dyn_info_t*);
121+
* extern void _U_dyn_cancel(unw_dyn_info_t*);
122+
*/
123+
124+
#ifdef __cplusplus
125+
}
126+
#endif
127+
128+
// architecture independent register numbers
129+
enum {
130+
UNW_REG_IP = -1, // instruction pointer
131+
UNW_REG_SP = -2, // stack pointer
132+
};
133+
134+
// 32-bit x86 registers
135+
enum {
136+
UNW_X86_EAX = 0,
137+
UNW_X86_ECX = 1,
138+
UNW_X86_EDX = 2,
139+
UNW_X86_EBX = 3,
140+
UNW_X86_EBP = 4,
141+
UNW_X86_ESP = 5,
142+
UNW_X86_ESI = 6,
143+
UNW_X86_EDI = 7
144+
};
145+
146+
// 64-bit x86_64 registers
147+
enum {
148+
UNW_X86_64_RAX = 0,
149+
UNW_X86_64_RDX = 1,
150+
UNW_X86_64_RCX = 2,
151+
UNW_X86_64_RBX = 3,
152+
UNW_X86_64_RSI = 4,
153+
UNW_X86_64_RDI = 5,
154+
UNW_X86_64_RBP = 6,
155+
UNW_X86_64_RSP = 7,
156+
UNW_X86_64_R8 = 8,
157+
UNW_X86_64_R9 = 9,
158+
UNW_X86_64_R10 = 10,
159+
UNW_X86_64_R11 = 11,
160+
UNW_X86_64_R12 = 12,
161+
UNW_X86_64_R13 = 13,
162+
UNW_X86_64_R14 = 14,
163+
UNW_X86_64_R15 = 15
164+
};
165+
166+
167+
// 32-bit ppc register numbers
168+
enum {
169+
UNW_PPC_R0 = 0,
170+
UNW_PPC_R1 = 1,
171+
UNW_PPC_R2 = 2,
172+
UNW_PPC_R3 = 3,
173+
UNW_PPC_R4 = 4,
174+
UNW_PPC_R5 = 5,
175+
UNW_PPC_R6 = 6,
176+
UNW_PPC_R7 = 7,
177+
UNW_PPC_R8 = 8,
178+
UNW_PPC_R9 = 9,
179+
UNW_PPC_R10 = 10,
180+
UNW_PPC_R11 = 11,
181+
UNW_PPC_R12 = 12,
182+
UNW_PPC_R13 = 13,
183+
UNW_PPC_R14 = 14,
184+
UNW_PPC_R15 = 15,
185+
UNW_PPC_R16 = 16,
186+
UNW_PPC_R17 = 17,
187+
UNW_PPC_R18 = 18,
188+
UNW_PPC_R19 = 19,
189+
UNW_PPC_R20 = 20,
190+
UNW_PPC_R21 = 21,
191+
UNW_PPC_R22 = 22,
192+
UNW_PPC_R23 = 23,
193+
UNW_PPC_R24 = 24,
194+
UNW_PPC_R25 = 25,
195+
UNW_PPC_R26 = 26,
196+
UNW_PPC_R27 = 27,
197+
UNW_PPC_R28 = 28,
198+
UNW_PPC_R29 = 29,
199+
UNW_PPC_R30 = 30,
200+
UNW_PPC_R31 = 31,
201+
UNW_PPC_F0 = 32,
202+
UNW_PPC_F1 = 33,
203+
UNW_PPC_F2 = 34,
204+
UNW_PPC_F3 = 35,
205+
UNW_PPC_F4 = 36,
206+
UNW_PPC_F5 = 37,
207+
UNW_PPC_F6 = 38,
208+
UNW_PPC_F7 = 39,
209+
UNW_PPC_F8 = 40,
210+
UNW_PPC_F9 = 41,
211+
UNW_PPC_F10 = 42,
212+
UNW_PPC_F11 = 43,
213+
UNW_PPC_F12 = 44,
214+
UNW_PPC_F13 = 45,
215+
UNW_PPC_F14 = 46,
216+
UNW_PPC_F15 = 47,
217+
UNW_PPC_F16 = 48,
218+
UNW_PPC_F17 = 49,
219+
UNW_PPC_F18 = 50,
220+
UNW_PPC_F19 = 51,
221+
UNW_PPC_F20 = 52,
222+
UNW_PPC_F21 = 53,
223+
UNW_PPC_F22 = 54,
224+
UNW_PPC_F23 = 55,
225+
UNW_PPC_F24 = 56,
226+
UNW_PPC_F25 = 57,
227+
UNW_PPC_F26 = 58,
228+
UNW_PPC_F27 = 59,
229+
UNW_PPC_F28 = 60,
230+
UNW_PPC_F29 = 61,
231+
UNW_PPC_F30 = 62,
232+
UNW_PPC_F31 = 63,
233+
UNW_PPC_MQ = 64,
234+
UNW_PPC_LR = 65,
235+
UNW_PPC_CTR = 66,
236+
UNW_PPC_AP = 67,
237+
UNW_PPC_CR0 = 68,
238+
UNW_PPC_CR1 = 69,
239+
UNW_PPC_CR2 = 70,
240+
UNW_PPC_CR3 = 71,
241+
UNW_PPC_CR4 = 72,
242+
UNW_PPC_CR5 = 73,
243+
UNW_PPC_CR6 = 74,
244+
UNW_PPC_CR7 = 75,
245+
UNW_PPC_XER = 76,
246+
UNW_PPC_V0 = 77,
247+
UNW_PPC_V1 = 78,
248+
UNW_PPC_V2 = 79,
249+
UNW_PPC_V3 = 80,
250+
UNW_PPC_V4 = 81,
251+
UNW_PPC_V5 = 82,
252+
UNW_PPC_V6 = 83,
253+
UNW_PPC_V7 = 84,
254+
UNW_PPC_V8 = 85,
255+
UNW_PPC_V9 = 86,
256+
UNW_PPC_V10 = 87,
257+
UNW_PPC_V11 = 88,
258+
UNW_PPC_V12 = 89,
259+
UNW_PPC_V13 = 90,
260+
UNW_PPC_V14 = 91,
261+
UNW_PPC_V15 = 92,
262+
UNW_PPC_V16 = 93,
263+
UNW_PPC_V17 = 94,
264+
UNW_PPC_V18 = 95,
265+
UNW_PPC_V19 = 96,
266+
UNW_PPC_V20 = 97,
267+
UNW_PPC_V21 = 98,
268+
UNW_PPC_V22 = 99,
269+
UNW_PPC_V23 = 100,
270+
UNW_PPC_V24 = 101,
271+
UNW_PPC_V25 = 102,
272+
UNW_PPC_V26 = 103,
273+
UNW_PPC_V27 = 104,
274+
UNW_PPC_V28 = 105,
275+
UNW_PPC_V29 = 106,
276+
UNW_PPC_V30 = 107,
277+
UNW_PPC_V31 = 108,
278+
UNW_PPC_VRSAVE = 109,
279+
UNW_PPC_VSCR = 110,
280+
UNW_PPC_SPE_ACC = 111,
281+
UNW_PPC_SPEFSCR = 112
282+
};
283+
284+
// 64-bit ARM64 registers
285+
enum {
286+
UNW_ARM64_X0 = 0,
287+
UNW_ARM64_X1 = 1,
288+
UNW_ARM64_X2 = 2,
289+
UNW_ARM64_X3 = 3,
290+
UNW_ARM64_X4 = 4,
291+
UNW_ARM64_X5 = 5,
292+
UNW_ARM64_X6 = 6,
293+
UNW_ARM64_X7 = 7,
294+
UNW_ARM64_X8 = 8,
295+
UNW_ARM64_X9 = 9,
296+
UNW_ARM64_X10 = 10,
297+
UNW_ARM64_X11 = 11,
298+
UNW_ARM64_X12 = 12,
299+
UNW_ARM64_X13 = 13,
300+
UNW_ARM64_X14 = 14,
301+
UNW_ARM64_X15 = 15,
302+
UNW_ARM64_X16 = 16,
303+
UNW_ARM64_X17 = 17,
304+
UNW_ARM64_X18 = 18,
305+
UNW_ARM64_X19 = 19,
306+
UNW_ARM64_X20 = 20,
307+
UNW_ARM64_X21 = 21,
308+
UNW_ARM64_X22 = 22,
309+
UNW_ARM64_X23 = 23,
310+
UNW_ARM64_X24 = 24,
311+
UNW_ARM64_X25 = 25,
312+
UNW_ARM64_X26 = 26,
313+
UNW_ARM64_X27 = 27,
314+
UNW_ARM64_X28 = 28,
315+
UNW_ARM64_X29 = 29,
316+
UNW_ARM64_FP = 29,
317+
UNW_ARM64_X30 = 30,
318+
UNW_ARM64_LR = 30,
319+
UNW_ARM64_X31 = 31,
320+
UNW_ARM64_SP = 31,
321+
// reserved block
322+
UNW_ARM64_D0 = 64,
323+
UNW_ARM64_D1 = 65,
324+
UNW_ARM64_D2 = 66,
325+
UNW_ARM64_D3 = 67,
326+
UNW_ARM64_D4 = 68,
327+
UNW_ARM64_D5 = 69,
328+
UNW_ARM64_D6 = 70,
329+
UNW_ARM64_D7 = 71,
330+
UNW_ARM64_D8 = 72,
331+
UNW_ARM64_D9 = 73,
332+
UNW_ARM64_D10 = 74,
333+
UNW_ARM64_D11 = 75,
334+
UNW_ARM64_D12 = 76,
335+
UNW_ARM64_D13 = 77,
336+
UNW_ARM64_D14 = 78,
337+
UNW_ARM64_D15 = 79,
338+
UNW_ARM64_D16 = 80,
339+
UNW_ARM64_D17 = 81,
340+
UNW_ARM64_D18 = 82,
341+
UNW_ARM64_D19 = 83,
342+
UNW_ARM64_D20 = 84,
343+
UNW_ARM64_D21 = 85,
344+
UNW_ARM64_D22 = 86,
345+
UNW_ARM64_D23 = 87,
346+
UNW_ARM64_D24 = 88,
347+
UNW_ARM64_D25 = 89,
348+
UNW_ARM64_D26 = 90,
349+
UNW_ARM64_D27 = 91,
350+
UNW_ARM64_D28 = 92,
351+
UNW_ARM64_D29 = 93,
352+
UNW_ARM64_D30 = 94,
353+
UNW_ARM64_D31 = 95,
354+
};
355+
356+
#endif

0 commit comments

Comments
 (0)