From f62b0dc1b66989bbae73093ed3f96ae98946be7f Mon Sep 17 00:00:00 2001
From: Charles Davis <cdavis5x@gmail.com>
Date: Tue, 5 Mar 2013 16:04:48 -0700
Subject: [PATCH] Headers/unwind.h: Flesh out.

This is more than enough to build libc++abi on Mac OS 10.6.

The change to the stdint.h header in the tests directory is needed to
make the tests succeed with these changes.
---
 lib/Headers/unwind.h                 |  155 ++++++++++++++++++++++++++++++++--
 test/Headers/Inputs/include/stdint.h |    1 +
 2 files changed, 149 insertions(+), 7 deletions(-)

diff --git a/lib/Headers/unwind.h b/lib/Headers/unwind.h
index e94fd70..a3703c7 100644
--- a/lib/Headers/unwind.h
+++ b/lib/Headers/unwind.h
@@ -27,9 +27,9 @@
 #define __CLANG_UNWIND_H
 
 #if __has_include_next(<unwind.h>)
-/* Darwin and libunwind provide an unwind.h. If that's available, use
- * it. libunwind wraps some of its definitions in #ifdef _GNU_SOURCE,
- * so define that around the include.*/
+/* Darwin (from 11.x on) and libunwind provide an unwind.h. If that's
+ * available, use it. libunwind wraps some of its definitions in
+ * #ifdef _GNU_SOURCE, so define that around the include.*/
 # ifndef _GNU_SOURCE
 #  define _SHOULD_UNDEFINE_GNU_SOURCE
 #  define _GNU_SOURCE
@@ -66,7 +66,21 @@ extern "C" {
 #pragma GCC visibility push(default)
 #endif
 
+/* Targets can override this to add custom attributes to certain functions. */
+#ifdef LIBGCC2_UNWIND_ATTRIBUTE
+# define UNWINDATTR LIBGCC2_UNWIND_ATTRIBUTE
+#else
+# define UNWINDATTR
+#endif
+
+typedef uintptr_t _Unwind_Word;
+typedef intptr_t _Unwind_Sword;
+typedef uintptr_t _Unwind_Ptr;
+typedef uintptr_t _Unwind_Internal_Ptr;
+typedef uint64_t _Unwind_Exception_Class;
+
 struct _Unwind_Context;
+struct _Unwind_Exception;
 typedef enum {
   _URC_NO_REASON = 0,
   _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
@@ -81,12 +95,53 @@ typedef enum {
   _URC_CONTINUE_UNWIND = 8
 } _Unwind_Reason_Code;
 
+typedef enum {
+  _UA_SEARCH_PHASE = 1,
+  _UA_CLEANUP_PHASE = 2,
+
+  _UA_HANDLER_FRAME = 4,
+  _UA_FORCE_UNWIND = 8,
+  _UA_END_OF_STACK = 16 /* gcc extension to C++ ABI */
+} _Unwind_Action;
+
+typedef void (*_Unwind_Exception_Cleanup_Fn)(_Unwind_Reason_Code,
+                                             struct _Unwind_Exception *);
+
+struct _Unwind_Exception {
+  _Unwind_Exception_Class exception_class;
+  _Unwind_Exception_Cleanup_Fn exception_cleanup;
+  _Unwind_Word private_1;
+  _Unwind_Word private_2;
+#if !defined(__LP64__) && !defined(_WIN64)
+  /* GCC's unwind.h uses the mode attribute on the _Unwind_* typedefs above.
+     As a side effect, this caused the size of this structure to round up to
+     32 bytes in size. Clang doesn't support the mode attribute, and probably
+     never will, so pad the struct up to 32 bytes manually for binary
+     compatibility with GCC-compiled programs. */
+  uint32_t reserved[3];
+#endif
+};
+
+typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)(int, _Unwind_Action,
+                                               _Unwind_Exception_Class,
+                                               struct _Unwind_Exception *,
+                                               struct _Unwind_Context *,
+                                               void *);
+
+typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)(int, _Unwind_Action,
+                                                      _Unwind_Exception_Class,
+                                                      struct _Unwind_Exception*,
+                                                      struct _Unwind_Context *);
+typedef _Unwind_Personality_Fn __personality_routine;
 
+typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context*, void*);
+
+/* ARM vector register stuff */
 #ifdef __arm__
 
 typedef enum {
   _UVRSC_CORE = 0,        /* integer register */
-  _UVRSC_VFP = 1,         /* vfp */
+  _UVRSC_VFP = 1,         /* Vector FP register */
   _UVRSC_WMMXD = 3,       /* Intel WMMX data register */
   _UVRSC_WMMXC = 4        /* Intel WMMX control register */
 } _Unwind_VRS_RegClass;
@@ -111,14 +166,100 @@ _Unwind_VRS_Result _Unwind_VRS_Get(struct _Unwind_Context *__context,
   _Unwind_VRS_DataRepresentation __representation,
   void *__valuep);
 
+#endif
+
+_Unwind_Word _Unwind_GetGR(struct _Unwind_Context *, int);
+void _Unwind_SetGR(struct _Unwind_Context *, int, _Unwind_Word);
+
+_Unwind_Word _Unwind_GetIP(struct _Unwind_Context *);
+_Unwind_Word _Unwind_GetIPInfo(struct _Unwind_Context *, int *);
+void _Unwind_SetIP(struct _Unwind_Context *, _Unwind_Word);
+
+_Unwind_Word _Unwind_GetCFA(struct _Unwind_Context *);
+
+void *_Unwind_GetLanguageSpecificData(struct _Unwind_Context *);
+
+_Unwind_Ptr _Unwind_GetRegionStart(struct _Unwind_Context *);
+
+/* DWARF EH functions; currently not available on Darwin/ARM */
+#if !defined(__APPLE__) || !defined(__arm__)
+
+_Unwind_Reason_Code UNWINDATTR
+  _Unwind_RaiseException(struct _Unwind_Exception *);
+_Unwind_Reason_Code UNWINDATTR _Unwind_ForcedUnwind(struct _Unwind_Exception *,
+                                                    _Unwind_Stop_Fn, void *);
+void _Unwind_DeleteException(struct _Unwind_Exception *);
+void UNWINDATTR _Unwind_Resume(struct _Unwind_Exception *);
+_Unwind_Reason_Code UNWINDATTR
+  _Unwind_Resume_or_Rethrow(struct _Unwind_Exception *);
+
+#endif
+
+_Unwind_Reason_Code UNWINDATTR _Unwind_Backtrace(_Unwind_Trace_Fn, void *);
+
+/* setjmp(3)/longjmp(3) stuff */
+typedef struct SjLj_Function_Context *_Unwind_FunctionContext_t;
+
+void _Unwind_SjLj_Register(_Unwind_FunctionContext_t);
+void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t);
+_Unwind_Reason_Code UNWINDATTR
+  _Unwind_SjLj_RaiseException(struct _Unwind_Exception *);
+_Unwind_Reason_Code UNWINDATTR
+  _Unwind_SjLj_ForcedUnwind(struct _Unwind_Exception *,_Unwind_Stop_Fn,void *);
+void UNWINDATTR _Unwind_SjLj_Resume(struct _Unwind_Exception *);
+_Unwind_Reason_Code UNWINDATTR
+  _Unwind_SjLj_Resume_or_Rethrow(struct _Unwind_Exception *);
+
+void *_Unwind_FindEnclosingFunction(void *);
+
+#ifdef __APPLE__
+
+/* Darwin doesn't even have any concept of data-relative or text-relative
+   addressing, because everything is section based. Mark these unavailable
+   there. */
+_Unwind_Ptr _Unwind_GetDataRelBase(struct _Unwind_Context *)
+  __attribute__((unavailable));
+_Unwind_Ptr _Unwind_GetTextRelBase(struct _Unwind_Context *)
+  __attribute__((unavailable));
+
+/* Darwin-specific functions */
+
+/* Functions for use with dynamically-generated (e.g. JIT) code. */
+void __register_frame(const void *);
+void __deregister_frame(const void *);
+
+/* Use this instead of _Unwind_FindEnclosingFunction() on Darwin. */
+struct dwarf_eh_bases {
+  uintptr_t tbase;
+  uintptr_t dbase;
+  uintptr_t func;
+};
+void *_Unwind_Find_FDE(const void *, struct dwarf_eh_bases *);
+
+/* Older functions that aren't available anymore on 10.6 and up
+   (and never really worked on 10.4/10.5). */
+void __register_frame_info_bases(const void *, void *, void *, void *)
+  __attribute__((unavailable));
+void __register_frame_info(const void *, void *) __attribute__((unavailable));
+void __register_frame_info_table_bases(const void *, void*, void *, void *)
+  __attribute__((unavailable));
+void __register_frame_info_table(const void *, void *)
+  __attribute__((unavailable));
+void __register_frame_table(const void *) __attribute__((unavailable));
+void __deregister_frame_info(const void *) __attribute__((unavailable));
+void __deregister_frame_info_bases(const void *)__attribute__((unavailable));
+
 #else
 
-uintptr_t _Unwind_GetIP(struct _Unwind_Context* __context);
+_Unwind_Ptr _Unwind_GetDataRelBase(struct _Unwind_Context *);
+_Unwind_Ptr _Unwind_GetTextRelBase(struct _Unwind_Context *);
 
 #endif
 
-typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context*, void*);
-_Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void*);
+/* LEB128 type definitions; should be big enough to hold any LEB128 that comes
+   up reading the unwind info. */
+typedef intptr_t _sleb128_t;
+typedef uintptr_t _uleb128_t;
 
 #ifndef HIDE_EXPORTS
 #pragma GCC visibility pop
diff --git a/test/Headers/Inputs/include/stdint.h b/test/Headers/Inputs/include/stdint.h
index 7a1fdde..5bf26a7 100644
--- a/test/Headers/Inputs/include/stdint.h
+++ b/test/Headers/Inputs/include/stdint.h
@@ -10,6 +10,7 @@ typedef unsigned __INT64_TYPE__ uint64_t;
 #endif
 
 #ifdef __INTPTR_TYPE__
+typedef __INTPTR_TYPE__ intptr_t;
 typedef unsigned __INTPTR_TYPE__ uintptr_t;
 #else
 #error Every target should have __INTPTR_TYPE__
-- 
1.7.5.4

