[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-30 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL341125: Add support for SEH unwinding on Windows. (authored 
by cdavis, committed by ).

Repository:
  rL LLVM

https://reviews.llvm.org/D50564

Files:
  libunwind/trunk/include/__libunwind_config.h
  libunwind/trunk/include/unwind.h
  libunwind/trunk/src/AddressSpace.hpp
  libunwind/trunk/src/CMakeLists.txt
  libunwind/trunk/src/Unwind-seh.cpp
  libunwind/trunk/src/UnwindCursor.hpp
  libunwind/trunk/src/UnwindLevel1-gcc-ext.c
  libunwind/trunk/src/UnwindLevel1.c
  libunwind/trunk/src/config.h

Index: libunwind/trunk/include/__libunwind_config.h
===
--- libunwind/trunk/include/__libunwind_config.h
+++ libunwind/trunk/include/__libunwind_config.h
@@ -34,7 +34,11 @@
 #  define _LIBUNWIND_TARGET_X86_64 1
 #  if defined(_WIN64)
 #define _LIBUNWIND_CONTEXT_SIZE 54
-#define _LIBUNWIND_CURSOR_SIZE 66
+#ifdef __SEH__
+#  define _LIBUNWIND_CURSOR_SIZE 204
+#else
+#  define _LIBUNWIND_CURSOR_SIZE 66
+#endif
 #  else
 #define _LIBUNWIND_CONTEXT_SIZE 21
 #define _LIBUNWIND_CURSOR_SIZE 33
@@ -57,7 +61,10 @@
 #  define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64
 # elif defined(__arm__)
 #  define _LIBUNWIND_TARGET_ARM 1
-#  if defined(__ARM_WMMX)
+#  if defined(__SEH__)
+#define _LIBUNWIND_CONTEXT_SIZE 42
+#define _LIBUNWIND_CURSOR_SIZE 85
+#  elif defined(__ARM_WMMX)
 #define _LIBUNWIND_CONTEXT_SIZE 61
 #define _LIBUNWIND_CURSOR_SIZE 68
 #  else
Index: libunwind/trunk/include/unwind.h
===
--- libunwind/trunk/include/unwind.h
+++ libunwind/trunk/include/unwind.h
@@ -19,8 +19,9 @@
 #include 
 #include 
 
-#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
+#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) && defined(_WIN32)
 #include 
+#include 
 #endif
 
 #if defined(__APPLE__)
@@ -378,12 +379,19 @@
 LIBUNWIND_UNAVAIL;
 
 #if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
+#ifndef _WIN32
+typedef struct _EXCEPTION_RECORD EXCEPTION_RECORD;
+typedef struct _CONTEXT CONTEXT;
+typedef struct _DISPATCHER_CONTEXT DISPATCHER_CONTEXT;
+#elif !defined(__MINGW32__) && VER_PRODUCTBUILD < 8000
+typedef struct _DISPATCHER_CONTEXT DISPATCHER_CONTEXT;
+#endif
 // This is the common wrapper for GCC-style personality functions with SEH.
-extern EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD exc,
-   PVOID frame,
-   PCONTEXT ctx,
-   PDISPATCHER_CONTEXT disp,
-   _Unwind_Personality_Fn pers);
+extern EXCEPTION_DISPOSITION _GCC_specific_handler(EXCEPTION_RECORD *exc,
+   void *frame,
+   CONTEXT *ctx,
+   DISPATCHER_CONTEXT *disp,
+   __personality_routine pers);
 #endif
 
 #ifdef __cplusplus
Index: libunwind/trunk/src/Unwind-seh.cpp
===
--- libunwind/trunk/src/Unwind-seh.cpp
+++ libunwind/trunk/src/Unwind-seh.cpp
@@ -0,0 +1,468 @@
+//===--- Unwind-seh.cpp ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+//
+//  Implements SEH-based Itanium C++ exceptions.
+//
+//===--===//
+
+#include "config.h"
+
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include "libunwind_ext.h"
+#include "UnwindCursor.hpp"
+
+using namespace libunwind;
+
+#define STATUS_USER_DEFINED (1u << 29)
+
+#define STATUS_GCC_MAGIC  (('G' << 16) | ('C' << 8) | 'C')
+
+#define MAKE_CUSTOM_STATUS(s, c) \
+  ((NTSTATUS)(((s) << 30) | STATUS_USER_DEFINED | (c)))
+#define MAKE_GCC_EXCEPTION(c) \
+  MAKE_CUSTOM_STATUS(STATUS_SEVERITY_SUCCESS, STATUS_GCC_MAGIC | ((c) << 24))
+
+/// SEH exception raised by libunwind when the program calls
+/// \c _Unwind_RaiseException.
+#define STATUS_GCC_THROW MAKE_GCC_EXCEPTION(0) // 0x20474343
+/// SEH exception raised by libunwind to initiate phase 2 of exception
+/// handling.
+#define STATUS_GCC_UNWIND MAKE_GCC_EXCEPTION(1) // 0x21474343
+
+/// Class of foreign exceptions based on unrecognized SEH exceptions.
+static const uint64_t kSEHExceptionClass = 0x434C4E4753454800; // CLNGSEH\0
+
+/// Exception cleanup ro

[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-30 Thread Reid Kleckner via Phabricator via cfe-commits
rnk accepted this revision.
rnk added a comment.
This revision is now accepted and ready to land.

In https://reviews.llvm.org/D50564#1211477, @mstorsjo wrote:

> Not much more comments from me. The implementation seems reasonable, and 
> works for one simple test I did (with an earlier revision of the patch at 
> least), and further refinement can happen in-tree I guess.
>
> I'd like to have someone else (@rnk @compnerd?) give it a more proper 
> approval though, at least a general ack for the style/structure.


Thanks, I found some time and looked through it. EH is super complicated, and I 
find that I'm not able to give meaningful feedback about how to simplify this 
code. In any case, I think we should go ahead and commit this and get some 
feedback from users.

Thanks for putting it together!


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-28 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x added a comment.

Ping.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-24 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x updated this revision to Diff 162509.
cdavis5x added a comment.

- Move `DISPATCHER_CONTEXT` definition into UnwindCursor.hpp.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564

Files:
  include/__libunwind_config.h
  include/unwind.h
  src/AddressSpace.hpp
  src/CMakeLists.txt
  src/Unwind-seh.cpp
  src/UnwindCursor.hpp
  src/UnwindLevel1-gcc-ext.c
  src/UnwindLevel1.c
  src/config.h

Index: src/config.h
===
--- src/config.h
+++ src/config.h
@@ -38,7 +38,11 @@
 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND   1
   #endif
 #elif defined(_WIN32)
-  #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
+  #ifdef __SEH__
+#define _LIBUNWIND_SUPPORT_SEH_UNWIND 1
+  #else
+#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
+  #endif
 #else
   #if defined(__ARM_DWARF_EH__) || !defined(__arm__)
 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
Index: src/UnwindLevel1.c
===
--- src/UnwindLevel1.c
+++ src/UnwindLevel1.c
@@ -32,6 +32,8 @@
 
 #if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__)
 
+#ifndef _LIBUNWIND_SUPPORT_SEH_UNWIND
+
 static _Unwind_Reason_Code
 unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
   unw_init_local(cursor, uc);
@@ -449,6 +451,7 @@
   return result;
 }
 
+#endif // !_LIBUNWIND_SUPPORT_SEH_UNWIND
 
 /// Called by personality handler during phase 2 if a foreign exception
 // is caught.
Index: src/UnwindLevel1-gcc-ext.c
===
--- src/UnwindLevel1-gcc-ext.c
+++ src/UnwindLevel1-gcc-ext.c
@@ -25,6 +25,10 @@
 
 #if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+#define private_1 private_[0]
+#endif
+
 ///  Called by __cxa_rethrow().
 _LIBUNWIND_EXPORT _Unwind_Reason_Code
 _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) {
Index: src/UnwindCursor.hpp
===
--- src/UnwindCursor.hpp
+++ src/UnwindCursor.hpp
@@ -18,10 +18,51 @@
 #include 
 #include 
 
+#ifdef _WIN32
+  #include 
+  #include 
+#endif
 #ifdef __APPLE__
   #include 
 #endif
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+// Provide a definition for the DISPATCHER_CONTEXT struct for old (Win7 and
+// earlier) SDKs.
+// MinGW-w64 has always provided this struct.
+  #if defined(_WIN32) && defined(_LIBUNWIND_TARGET_X86_64) && \
+  !defined(__MINGW32__) && VER_PRODUCTBUILD < 8000
+struct _DISPATCHER_CONTEXT {
+  ULONG64 ControlPc;
+  ULONG64 ImageBase;
+  PRUNTIME_FUNCTION FunctionEntry;
+  ULONG64 EstablisherFrame;
+  ULONG64 TargetIp;
+  PCONTEXT ContextRecord;
+  PEXCEPTION_ROUTINE LanguageHandler;
+  PVOID HandlerData;
+  PUNWIND_HISTORY_TABLE HistoryTable;
+  ULONG ScopeIndex;
+  ULONG Fill0;
+};
+  #endif
+
+struct UNWIND_INFO {
+  uint8_t Version : 3;
+  uint8_t Flags : 5;
+  uint8_t SizeOfProlog;
+  uint8_t CountOfCodes;
+  uint8_t FrameRegister : 4;
+  uint8_t FrameOffset : 4;
+  uint16_t UnwindCodes[2];
+};
+
+extern "C" _Unwind_Reason_Code __libunwind_seh_personality(
+int, _Unwind_Action, uint64_t, _Unwind_Exception *,
+struct _Unwind_Context *);
+
+#endif
+
 #include "config.h"
 
 #include "AddressSpace.hpp"
@@ -412,6 +453,472 @@
 #endif
 };
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && defined(_WIN32)
+
+/// \c UnwindCursor contains all state (including all register values) during
+/// an unwind.  This is normally stack-allocated inside a unw_cursor_t.
+template 
+class UnwindCursor : public AbstractUnwindCursor {
+  typedef typename A::pint_t pint_t;
+public:
+  UnwindCursor(unw_context_t *context, A &as);
+  UnwindCursor(CONTEXT *context, A &as);
+  UnwindCursor(A &as, void *threadArg);
+  virtual ~UnwindCursor() {}
+  virtual boolvalidReg(int);
+  virtual unw_word_t  getReg(int);
+  virtual voidsetReg(int, unw_word_t);
+  virtual boolvalidFloatReg(int);
+  virtual unw_fpreg_t getFloatReg(int);
+  virtual voidsetFloatReg(int, unw_fpreg_t);
+  virtual int step();
+  virtual voidgetInfo(unw_proc_info_t *);
+  virtual voidjumpto();
+  virtual boolisSignalFrame();
+  virtual boolgetFunctionName(char *buf, size_t len, unw_word_t *off);
+  virtual voidsetInfoBasedOnIPRegister(bool isReturnAddress = false);
+  virtual const char *getRegisterName(int num);
+#ifdef __arm__
+  virtual voidsaveVFPAsX();
+#endif
+
+  DISPATCHER_CONTEXT *getDispatcherContext() { return &_dispContext; }
+  void setDispatcherContext(DISPATCHER_CONTEXT *disp) { _dispContext = *disp; }
+
+private:
+
+  pint_t getLastPC() const { return _dispContext.ControlPc; }
+  void setLastPC(pint_t pc) { _dispContext.ControlPc = pc; }
+  RUNTIME_FUNCTION *lookUpSEHUnwindInfo(pint_t pc, pint_t *base) {
+_dispContext.Functio

[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-24 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x updated this revision to Diff 162441.
cdavis5x marked 8 inline comments as done.
cdavis5x added a comment.

- Remove case we'll never realistically hit.
- Add back include I removed earlier.
- Add a comment clarifying that some environments use SEH without Windows 
runtime support.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564

Files:
  include/__libunwind_config.h
  include/unwind.h
  src/AddressSpace.hpp
  src/CMakeLists.txt
  src/Unwind-seh.cpp
  src/UnwindCursor.hpp
  src/UnwindLevel1-gcc-ext.c
  src/UnwindLevel1.c
  src/config.h
  src/libunwind_ext.h

Index: src/libunwind_ext.h
===
--- src/libunwind_ext.h
+++ src/libunwind_ext.h
@@ -17,6 +17,12 @@
 #include 
 #include 
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && defined(_WIN32)
+  #include 
+  #include 
+  #include 
+#endif
+
 #define UNW_STEP_SUCCESS 1
 #define UNW_STEP_END 0
 
@@ -33,6 +39,30 @@
 extern void _unw_add_dynamic_fde(unw_word_t fde);
 extern void _unw_remove_dynamic_fde(unw_word_t fde);
 
+// Provide a definition for the DISPATCHER_CONTEXT struct for old (Win7 and
+// earlier) SDKs.
+// MinGW-w64 has always provided this struct.
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && !defined(__MINGW32__) && VER_PRODUCTBUILD < 8000
+  #ifdef _WIN32
+#if defined(__x86_64__)
+struct _DISPATCHER_CONTEXT {
+  ULONG64 ControlPc;
+  ULONG64 ImageBase;
+  PRUNTIME_FUNCTION FunctionEntry;
+  ULONG64 EstablisherFrame;
+  ULONG64 TargetIp;
+  PCONTEXT ContextRecord;
+  PEXCEPTION_ROUTINE LanguageHandler;
+  PVOID HandlerData;
+  PUNWIND_HISTORY_TABLE HistoryTable;
+  ULONG ScopeIndex;
+  ULONG Fill0;
+};
+#endif
+  #endif
+typedef DISPATCHER_CONTEXT* PDISPATCHER_CONTEXT;
+#endif
+
 #if defined(_LIBUNWIND_ARM_EHABI)
 extern const uint32_t* decode_eht_entry(const uint32_t*, size_t*, size_t*);
 extern _Unwind_Reason_Code _Unwind_VRS_Interpret(_Unwind_Context *context,
Index: src/config.h
===
--- src/config.h
+++ src/config.h
@@ -38,7 +38,11 @@
 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND   1
   #endif
 #elif defined(_WIN32)
-  #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
+  #ifdef __SEH__
+#define _LIBUNWIND_SUPPORT_SEH_UNWIND 1
+  #else
+#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
+  #endif
 #else
   #if defined(__ARM_DWARF_EH__) || !defined(__arm__)
 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
Index: src/UnwindLevel1.c
===
--- src/UnwindLevel1.c
+++ src/UnwindLevel1.c
@@ -32,6 +32,8 @@
 
 #if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__)
 
+#ifndef _LIBUNWIND_SUPPORT_SEH_UNWIND
+
 static _Unwind_Reason_Code
 unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
   unw_init_local(cursor, uc);
@@ -449,6 +451,7 @@
   return result;
 }
 
+#endif // !_LIBUNWIND_SUPPORT_SEH_UNWIND
 
 /// Called by personality handler during phase 2 if a foreign exception
 // is caught.
Index: src/UnwindLevel1-gcc-ext.c
===
--- src/UnwindLevel1-gcc-ext.c
+++ src/UnwindLevel1-gcc-ext.c
@@ -25,6 +25,10 @@
 
 #if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+#define private_1 private_[0]
+#endif
+
 ///  Called by __cxa_rethrow().
 _LIBUNWIND_EXPORT _Unwind_Reason_Code
 _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) {
Index: src/UnwindCursor.hpp
===
--- src/UnwindCursor.hpp
+++ src/UnwindCursor.hpp
@@ -18,10 +18,30 @@
 #include 
 #include 
 
+#ifdef _WIN32
+  #include 
+#endif
 #ifdef __APPLE__
   #include 
 #endif
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+struct UNWIND_INFO {
+  uint8_t Version : 3;
+  uint8_t Flags : 5;
+  uint8_t SizeOfProlog;
+  uint8_t CountOfCodes;
+  uint8_t FrameRegister : 4;
+  uint8_t FrameOffset : 4;
+  uint16_t UnwindCodes[2];
+};
+
+extern "C" _Unwind_Reason_Code __libunwind_seh_personality(
+int, _Unwind_Action, uint64_t, _Unwind_Exception *,
+struct _Unwind_Context *);
+
+#endif
+
 #include "config.h"
 
 #include "AddressSpace.hpp"
@@ -412,6 +432,472 @@
 #endif
 };
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && defined(_WIN32)
+
+/// \c UnwindCursor contains all state (including all register values) during
+/// an unwind.  This is normally stack-allocated inside a unw_cursor_t.
+template 
+class UnwindCursor : public AbstractUnwindCursor {
+  typedef typename A::pint_t pint_t;
+public:
+  UnwindCursor(unw_context_t *context, A &as);
+  UnwindCursor(CONTEXT *context, A &as);
+  UnwindCursor(A &as, void *threadArg);
+  virtual ~UnwindCursor() {}
+  virtual boolvalidReg(int);
+  virtual unw_word_t  getReg(int);
+  virtual voidsetReg(int, unw_word_t);
+  virtual bool

[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-23 Thread Kristina Brooks via Phabricator via cfe-commits
kristina added a comment.

I'd say LGTM since it's an introduction of any sort of **runtime** within the 
LLVM project scope that deals with SEH specifically. So far all the published 
code is pretty much exclusively related to Clang/LLVM IR and MC support for 
codegen of SEH related code, but with an implicit reliance on core Windows 
runtime and other goodies being around. Even if not super polished, as long as 
it does not cause regressions in other parts of libunwind, it's a start 
nontheless.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-23 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo added a comment.

Not much more comments from me. The implementation seems reasonable, and works 
for one simple test I did (with an earlier revision of the patch at least), and 
further refinement can happen in-tree I guess.

I'd like to have someone else (@rnk @compnerd?) give it a more proper approval 
though, at least a general ack for the style/structure.




Comment at: include/__libunwind_config.h:66
+#if defined(__ARM_WMMX)
+#  define _LIBUNWIND_CONTEXT_SIZE 61
+#else

I don't think the `__ARM_WMMX` case here is relevant; there are no ARM CPUs 
with WMMX running modern windows on arm, afaik (and the size number here I 
presume only is a copy from the one below); sorry for not pointing it out 
earlier.



Comment at: src/UnwindCursor.hpp:54
 #include "EHHeaderParser.hpp"
-#include "libunwind.h"
+#include "libunwind_ext.h"
 #include "Registers.hpp"

mstorsjo wrote:
> This looks like another leftover; there's no `libunwind_ext.h` any longer 
> here.
Sorry I think I misread and looked for `libunwind_ext.h` in the `include` dir 
only. But in case it isn't really needed here, keep the old `libunwind.h` 
include at least, in order not to break other potential build configurations 
that might need it.



Comment at: src/UnwindCursor.hpp:1157
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+  pint_t getLastPC() const { /* FIXME: Implement */ return 0; }

cdavis5x wrote:
> mstorsjo wrote:
> > What does this whole block do here? Isn't this within an !SEH ifdef block? 
> > The same methods are declared for the SEH version of this struct further 
> > above.
> Right now, it doesn't do anything. I added it so @kristina has someplace to 
> put the code for unwinding with SEH data when we're //not// on Windows and we 
> //don't// have the `RtlUnwindEx()` function available. You'll note that the 
> '!SEH' `ifdef` now says:
> 
> ```lang=c++
> #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && defined(_WIN32)
> ```
Ah, I see. Maybe a comment clarifying that here as well?


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-23 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x marked 2 inline comments as done.
cdavis5x added inline comments.



Comment at: src/Unwind-seh.cpp:163
+#ifdef __x86_64__
+unw_get_reg(&cursor, UNW_X86_64_RAX, &retval);
+unw_get_reg(&cursor, UNW_X86_64_RDX, &exc->private_[3]);

mstorsjo wrote:
> Without understanding the code flow completely - is there a risk that this 
> tries to use an uninitialized cursor, in case we hit `ctx = (struct 
> _Unwind_Context *)ms_exc->ExceptionInformation[1];` above and never 
> initialized the local cursor?
We should only hit this point if we're in phase 2 (i.e. 
`IS_UNWINDING(exc->ExceptionFlags)` is true). But you've now got me worried 
about the potential for a rogue personality function surreptitiously returning 
this to exploit libunwind. I've added a check here.



Comment at: src/Unwind-seh.cpp:174
+CONTEXT new_ctx;
+RtlUnwindEx(frame, (PVOID)target, ms_exc, (PVOID)retval, &new_ctx, 
disp->HistoryTable);
+_LIBUNWIND_ABORT("RtlUnwindEx() failed");

mstorsjo wrote:
> Who will get this new uninitialized CONTEXT here, and will they try to use it 
> for something?
It won't be uninitialized. `RtlUnwindEx()` always starts unwinding from the 
current frame; it fills in the passed in `CONTEXT` and passes its address to 
any handlers it encounters along the way. In other words, it's there so 
`RtlUnwindEx()` has a place to keep track of the unwind context.



Comment at: src/UnwindCursor.hpp:1157
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+  pint_t getLastPC() const { /* FIXME: Implement */ return 0; }

mstorsjo wrote:
> What does this whole block do here? Isn't this within an !SEH ifdef block? 
> The same methods are declared for the SEH version of this struct further 
> above.
Right now, it doesn't do anything. I added it so @kristina has someplace to put 
the code for unwinding with SEH data when we're //not// on Windows and we 
//don't// have the `RtlUnwindEx()` function available. You'll note that the 
'!SEH' `ifdef` now says:

```lang=c++
#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && defined(_WIN32)
```



Comment at: src/UnwindCursor.hpp:1801
+  if (pc != getLastPC()) {
+UNWIND_INFO *xdata = reinterpret_cast(base + 
unwindEntry->UnwindData);
+if (xdata->Flags & (UNW_FLAG_EHANDLER|UNW_FLAG_UHANDLER)) {

kristina wrote:
> mstorsjo wrote:
> > I can't say I understand all of this yet, but I'm slowly getting there, and 
> > I'm trying to compare this to what libgcc does.
> > 
> > libgcc doesn't use any definition of UNWIND_INFO and doesn't need to do the 
> > equivalent of `getInfoFromSEH`, used by `step()`, anywhere. `unw_step()` is 
> > used in `_Unwind_ForcedUnwind`, which in libgcc is implemented using 
> > `RaiseException (STATUS_GCC_FORCED, ...`.
> > 
> > I guess if you happen to have all of the `unw_step` API available, it's 
> > easier to just do it like this, in custom code without relying on the NTDLL 
> > functions for it, while the libgcc version relies more on the NTDLL API.
> This primarily deals with the SEH exceptions re-purposed as a C++ exception 
> mechanism on x86_64 (if I understood this right), it's possible to set a 
> custom filter using a runtime call so I suspect GCC does that or defines a 
> translation function (also via a runtime call) which acts as a filter for 
> "true" SEH exceptions behind the scenes deep within the runtime. Typially 
> "true" SEH exceptions don't, outside of runtime magic, play nicely with C++ 
> exceptions, with the `__C_specific_handler` ones being a completely different 
> paradigm that falls far outside the scope of libunwind (those ones being the 
> "true"/explicit SEH exceptions).
> 
> (Don't take my word for it, it's been a while and I only implemented the 
> "true" variation for 64-bit Linux by reserving some RT signals and using that 
> to invoke additional runtime glue that would then do the unwinding, 
> completely ignoring DWARF since CFI exceptions and SEH exceptions really 
> don't mix especially on platforms that are not Windows-like)
Actually, it's just to implement the lower-level `libunwind` 
APIs--specifically, `unw_get_info()`. The code @kristina is talking about is 
all in Unwind-seh.cpp.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-23 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x updated this revision to Diff 162250.
cdavis5x marked 7 inline comments as done.
cdavis5x added a comment.

- Remove unnecessary code.
- Guard against rogue personality functions returning wrong values.
- Add a comment clarifying the purpose of the `new_ctx` variable.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564

Files:
  include/__libunwind_config.h
  include/unwind.h
  src/AddressSpace.hpp
  src/CMakeLists.txt
  src/Unwind-seh.cpp
  src/UnwindCursor.hpp
  src/UnwindLevel1-gcc-ext.c
  src/UnwindLevel1.c
  src/config.h
  src/libunwind_ext.h

Index: src/libunwind_ext.h
===
--- src/libunwind_ext.h
+++ src/libunwind_ext.h
@@ -17,6 +17,12 @@
 #include 
 #include 
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && defined(_WIN32)
+  #include 
+  #include 
+  #include 
+#endif
+
 #define UNW_STEP_SUCCESS 1
 #define UNW_STEP_END 0
 
@@ -33,6 +39,30 @@
 extern void _unw_add_dynamic_fde(unw_word_t fde);
 extern void _unw_remove_dynamic_fde(unw_word_t fde);
 
+// Provide a definition for the DISPATCHER_CONTEXT struct for old (Win7 and
+// earlier) SDKs.
+// MinGW-w64 has always provided this struct.
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && !defined(__MINGW32__) && VER_PRODUCTBUILD < 8000
+  #ifdef _WIN32
+#if defined(__x86_64__)
+struct _DISPATCHER_CONTEXT {
+  ULONG64 ControlPc;
+  ULONG64 ImageBase;
+  PRUNTIME_FUNCTION FunctionEntry;
+  ULONG64 EstablisherFrame;
+  ULONG64 TargetIp;
+  PCONTEXT ContextRecord;
+  PEXCEPTION_ROUTINE LanguageHandler;
+  PVOID HandlerData;
+  PUNWIND_HISTORY_TABLE HistoryTable;
+  ULONG ScopeIndex;
+  ULONG Fill0;
+};
+#endif
+  #endif
+typedef DISPATCHER_CONTEXT* PDISPATCHER_CONTEXT;
+#endif
+
 #if defined(_LIBUNWIND_ARM_EHABI)
 extern const uint32_t* decode_eht_entry(const uint32_t*, size_t*, size_t*);
 extern _Unwind_Reason_Code _Unwind_VRS_Interpret(_Unwind_Context *context,
Index: src/config.h
===
--- src/config.h
+++ src/config.h
@@ -38,7 +38,11 @@
 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND   1
   #endif
 #elif defined(_WIN32)
-  #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
+  #ifdef __SEH__
+#define _LIBUNWIND_SUPPORT_SEH_UNWIND 1
+  #else
+#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
+  #endif
 #else
   #if defined(__ARM_DWARF_EH__) || !defined(__arm__)
 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
Index: src/UnwindLevel1.c
===
--- src/UnwindLevel1.c
+++ src/UnwindLevel1.c
@@ -32,6 +32,8 @@
 
 #if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__)
 
+#ifndef _LIBUNWIND_SUPPORT_SEH_UNWIND
+
 static _Unwind_Reason_Code
 unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
   unw_init_local(cursor, uc);
@@ -449,6 +451,7 @@
   return result;
 }
 
+#endif // !_LIBUNWIND_SUPPORT_SEH_UNWIND
 
 /// Called by personality handler during phase 2 if a foreign exception
 // is caught.
Index: src/UnwindLevel1-gcc-ext.c
===
--- src/UnwindLevel1-gcc-ext.c
+++ src/UnwindLevel1-gcc-ext.c
@@ -25,6 +25,10 @@
 
 #if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+#define private_1 private_[0]
+#endif
+
 ///  Called by __cxa_rethrow().
 _LIBUNWIND_EXPORT _Unwind_Reason_Code
 _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) {
Index: src/UnwindCursor.hpp
===
--- src/UnwindCursor.hpp
+++ src/UnwindCursor.hpp
@@ -18,18 +18,37 @@
 #include 
 #include 
 
+#ifdef _WIN32
+  #include 
+#endif
 #ifdef __APPLE__
   #include 
 #endif
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+struct UNWIND_INFO {
+  uint8_t Version : 3;
+  uint8_t Flags : 5;
+  uint8_t SizeOfProlog;
+  uint8_t CountOfCodes;
+  uint8_t FrameRegister : 4;
+  uint8_t FrameOffset : 4;
+  uint16_t UnwindCodes[2];
+};
+
+extern "C" _Unwind_Reason_Code __libunwind_seh_personality(
+int, _Unwind_Action, uint64_t, _Unwind_Exception *,
+struct _Unwind_Context *);
+
+#endif
+
 #include "config.h"
 
 #include "AddressSpace.hpp"
 #include "CompactUnwinder.hpp"
 #include "config.h"
 #include "DwarfInstructions.hpp"
 #include "EHHeaderParser.hpp"
-#include "libunwind.h"
 #include "Registers.hpp"
 #include "RWMutex.hpp"
 #include "Unwind-EHABI.h"
@@ -412,6 +431,472 @@
 #endif
 };
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && defined(_WIN32)
+
+/// \c UnwindCursor contains all state (including all register values) during
+/// an unwind.  This is normally stack-allocated inside a unw_cursor_t.
+template 
+class UnwindCursor : public AbstractUnwindCursor {
+  typedef typename A::pint_t pint_t;
+public:
+  UnwindCursor(unw_context_t *context, A &as);
+  UnwindCursor(CONTEXT *context, A &as);
+  UnwindCursor(A &as, 

[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-23 Thread Kristina Brooks via Phabricator via cfe-commits
kristina added inline comments.



Comment at: src/UnwindCursor.hpp:1801
+  if (pc != getLastPC()) {
+UNWIND_INFO *xdata = reinterpret_cast(base + 
unwindEntry->UnwindData);
+if (xdata->Flags & (UNW_FLAG_EHANDLER|UNW_FLAG_UHANDLER)) {

mstorsjo wrote:
> I can't say I understand all of this yet, but I'm slowly getting there, and 
> I'm trying to compare this to what libgcc does.
> 
> libgcc doesn't use any definition of UNWIND_INFO and doesn't need to do the 
> equivalent of `getInfoFromSEH`, used by `step()`, anywhere. `unw_step()` is 
> used in `_Unwind_ForcedUnwind`, which in libgcc is implemented using 
> `RaiseException (STATUS_GCC_FORCED, ...`.
> 
> I guess if you happen to have all of the `unw_step` API available, it's 
> easier to just do it like this, in custom code without relying on the NTDLL 
> functions for it, while the libgcc version relies more on the NTDLL API.
This primarily deals with the SEH exceptions re-purposed as a C++ exception 
mechanism on x86_64 (if I understood this right), it's possible to set a custom 
filter using a runtime call so I suspect GCC does that or defines a translation 
function (also via a runtime call) which acts as a filter for "true" SEH 
exceptions behind the scenes deep within the runtime. Typially "true" SEH 
exceptions don't, outside of runtime magic, play nicely with C++ exceptions, 
with the `__C_specific_handler` ones being a completely different paradigm that 
falls far outside the scope of libunwind (those ones being the "true"/explicit 
SEH exceptions).

(Don't take my word for it, it's been a while and I only implemented the "true" 
variation for 64-bit Linux by reserving some RT signals and using that to 
invoke additional runtime glue that would then do the unwinding, completely 
ignoring DWARF since CFI exceptions and SEH exceptions really don't mix 
especially on platforms that are not Windows-like)


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-23 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo added inline comments.



Comment at: src/Unwind-seh.cpp:163
+#ifdef __x86_64__
+unw_get_reg(&cursor, UNW_X86_64_RAX, &retval);
+unw_get_reg(&cursor, UNW_X86_64_RDX, &exc->private_[3]);

Without understanding the code flow completely - is there a risk that this 
tries to use an uninitialized cursor, in case we hit `ctx = (struct 
_Unwind_Context *)ms_exc->ExceptionInformation[1];` above and never initialized 
the local cursor?



Comment at: src/Unwind-seh.cpp:174
+CONTEXT new_ctx;
+RtlUnwindEx(frame, (PVOID)target, ms_exc, (PVOID)retval, &new_ctx, 
disp->HistoryTable);
+_LIBUNWIND_ABORT("RtlUnwindEx() failed");

Who will get this new uninitialized CONTEXT here, and will they try to use it 
for something?



Comment at: src/UnwindCursor.hpp:31
+struct UNWIND_INFO {
+  uint8_t Version : 3;
+  uint8_t Flags : 5;

Hmm, I think this one is supposed to be arch independent. Although it's easy to 
remove the ifdef once we want to use it for anything else than x86_64...



Comment at: src/UnwindCursor.hpp:54
 #include "EHHeaderParser.hpp"
-#include "libunwind.h"
+#include "libunwind_ext.h"
 #include "Registers.hpp"

This looks like another leftover; there's no `libunwind_ext.h` any longer here.



Comment at: src/UnwindCursor.hpp:482
+  int stepWithSEHData() {
+#if !defined(_LIBUNWIND_TARGET_I386)
+_dispContext.LanguageHandler = RtlVirtualUnwind(UNW_FLAG_UHANDLER,

Maybe skip the i386 ifdefs here, to keep it concise, as we don't expect to 
build this with `__SEH__` defined for i386.



Comment at: src/UnwindCursor.hpp:625
+  memset(&_histTable, 0, sizeof(_histTable));
+  // FIXME
+  // fill in _registers from thread arg

If this constructor is unused and unimplemented, I'd omit it altogether.



Comment at: src/UnwindCursor.hpp:1157
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+  pint_t getLastPC() const { /* FIXME: Implement */ return 0; }

What does this whole block do here? Isn't this within an !SEH ifdef block? The 
same methods are declared for the SEH version of this struct further above.



Comment at: src/UnwindCursor.hpp:1801
+  if (pc != getLastPC()) {
+UNWIND_INFO *xdata = reinterpret_cast(base + 
unwindEntry->UnwindData);
+if (xdata->Flags & (UNW_FLAG_EHANDLER|UNW_FLAG_UHANDLER)) {

I can't say I understand all of this yet, but I'm slowly getting there, and I'm 
trying to compare this to what libgcc does.

libgcc doesn't use any definition of UNWIND_INFO and doesn't need to do the 
equivalent of `getInfoFromSEH`, used by `step()`, anywhere. `unw_step()` is 
used in `_Unwind_ForcedUnwind`, which in libgcc is implemented using 
`RaiseException (STATUS_GCC_FORCED, ...`.

I guess if you happen to have all of the `unw_step` API available, it's easier 
to just do it like this, in custom code without relying on the NTDLL functions 
for it, while the libgcc version relies more on the NTDLL API.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-21 Thread Kristina Brooks via Phabricator via cfe-commits
kristina added a comment.

In https://reviews.llvm.org/D50564#1208169, @cdavis5x wrote:

> OK, I've removed some of the dependencies on Windows-specific types. The code 
> in `Unwind-seh.cpp` is very Windows-specific, though, so I left it alone.


Much appreciated, thank you for your work. LGTM in terms of semantics.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-21 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x added a comment.

OK, I've removed some of the dependencies on Windows-specific types. The code 
in `Unwind-seh.cpp` is very Windows-specific, though, so I left it alone.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-21 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x updated this revision to Diff 161807.
cdavis5x added a comment.

- Make a bit more friendly to non-Windows.
- Fix bits that depend on https://reviews.llvm.org/D50413.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564

Files:
  include/__libunwind_config.h
  include/unwind.h
  src/AddressSpace.hpp
  src/CMakeLists.txt
  src/Unwind-seh.cpp
  src/UnwindCursor.hpp
  src/UnwindLevel1-gcc-ext.c
  src/UnwindLevel1.c
  src/config.h
  src/libunwind_ext.h

Index: src/libunwind_ext.h
===
--- src/libunwind_ext.h
+++ src/libunwind_ext.h
@@ -17,6 +17,12 @@
 #include 
 #include 
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && defined(_WIN32)
+  #include 
+  #include 
+  #include 
+#endif
+
 #define UNW_STEP_SUCCESS 1
 #define UNW_STEP_END 0
 
@@ -33,6 +39,30 @@
 extern void _unw_add_dynamic_fde(unw_word_t fde);
 extern void _unw_remove_dynamic_fde(unw_word_t fde);
 
+// Provide a definition for the DISPATCHER_CONTEXT struct for old (Win7 and
+// earlier) SDKs.
+// MinGW-w64 has always provided this struct.
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && !defined(__MINGW32__) && VER_PRODUCTBUILD < 8000
+  #ifdef _WIN32
+#if defined(__x86_64__)
+struct _DISPATCHER_CONTEXT {
+  ULONG64 ControlPc;
+  ULONG64 ImageBase;
+  PRUNTIME_FUNCTION FunctionEntry;
+  ULONG64 EstablisherFrame;
+  ULONG64 TargetIp;
+  PCONTEXT ContextRecord;
+  PEXCEPTION_ROUTINE LanguageHandler;
+  PVOID HandlerData;
+  PUNWIND_HISTORY_TABLE HistoryTable;
+  ULONG ScopeIndex;
+  ULONG Fill0;
+};
+#endif
+  #endif
+typedef DISPATCHER_CONTEXT* PDISPATCHER_CONTEXT;
+#endif
+
 #if defined(_LIBUNWIND_ARM_EHABI)
 extern const uint32_t* decode_eht_entry(const uint32_t*, size_t*, size_t*);
 extern _Unwind_Reason_Code _Unwind_VRS_Interpret(_Unwind_Context *context,
Index: src/config.h
===
--- src/config.h
+++ src/config.h
@@ -38,7 +38,11 @@
 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND   1
   #endif
 #elif defined(_WIN32)
-  #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
+  #ifdef __SEH__
+#define _LIBUNWIND_SUPPORT_SEH_UNWIND 1
+  #else
+#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
+  #endif
 #else
   #if defined(__ARM_DWARF_EH__) || !defined(__arm__)
 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
Index: src/UnwindLevel1.c
===
--- src/UnwindLevel1.c
+++ src/UnwindLevel1.c
@@ -32,6 +32,8 @@
 
 #if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__)
 
+#ifndef _LIBUNWIND_SUPPORT_SEH_UNWIND
+
 static _Unwind_Reason_Code
 unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
   unw_init_local(cursor, uc);
@@ -449,6 +451,7 @@
   return result;
 }
 
+#endif // !_LIBUNWIND_SUPPORT_SEH_UNWIND
 
 /// Called by personality handler during phase 2 if a foreign exception
 // is caught.
Index: src/UnwindLevel1-gcc-ext.c
===
--- src/UnwindLevel1-gcc-ext.c
+++ src/UnwindLevel1-gcc-ext.c
@@ -25,6 +25,10 @@
 
 #if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+#define private_1 private_[0]
+#endif
+
 ///  Called by __cxa_rethrow().
 _LIBUNWIND_EXPORT _Unwind_Reason_Code
 _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) {
Index: src/UnwindCursor.hpp
===
--- src/UnwindCursor.hpp
+++ src/UnwindCursor.hpp
@@ -18,18 +18,40 @@
 #include 
 #include 
 
+#ifdef _WIN32
+  #include 
+#endif
 #ifdef __APPLE__
   #include 
 #endif
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+#  ifdef _LIBUNWIND_TARGET_X86_64
+struct UNWIND_INFO {
+  uint8_t Version : 3;
+  uint8_t Flags : 5;
+  uint8_t SizeOfProlog;
+  uint8_t CountOfCodes;
+  uint8_t FrameRegister : 4;
+  uint8_t FrameOffset : 4;
+  uint16_t UnwindCodes[2];
+};
+#  endif
+
+extern "C" _Unwind_Reason_Code __libunwind_seh_personality(
+int, _Unwind_Action, uint64_t, _Unwind_Exception *,
+struct _Unwind_Context *);
+
+#endif
+
 #include "config.h"
 
 #include "AddressSpace.hpp"
 #include "CompactUnwinder.hpp"
 #include "config.h"
 #include "DwarfInstructions.hpp"
 #include "EHHeaderParser.hpp"
-#include "libunwind.h"
+#include "libunwind_ext.h"
 #include "Registers.hpp"
 #include "RWMutex.hpp"
 #include "Unwind-EHABI.h"
@@ -412,6 +434,487 @@
 #endif
 };
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && defined(_WIN32)
+
+/// \c UnwindCursor contains all state (including all register values) during
+/// an unwind.  This is normally stack-allocated inside a unw_cursor_t.
+template 
+class UnwindCursor : public AbstractUnwindCursor {
+  typedef typename A::pint_t pint_t;
+public:
+  UnwindCursor(unw_context_t *context, A &as);
+  UnwindCursor(CONTEXT *context, A &as);
+  UnwindCursor(A &as, void *threadArg);
+  virtual 

[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-21 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x added a comment.

In https://reviews.llvm.org/D50564#1207493, @kristina wrote:

> In https://reviews.llvm.org/D50564#1206393, @mstorsjo wrote:
>
> > In https://reviews.llvm.org/D50564#1206370, @cdavis5x wrote:
> >
> > > In https://reviews.llvm.org/D50564#1206302, @kristina wrote:
> > >
> > > > I'm all for this change except the core issue is that you're using 
> > > > libunwind as a shim around the actual unwinding API provided by 
> > > > Windows. It would be nice to have something that did not have to do 
> > > > that and was capable of performing unwinding of SEH-style exceptions 
> > > > without needing additional runtime support.
> > >
> > >
> > > It would be nice, but that would require extra work. We'd have to 
> > > implement reading and interpreting unwind codes, and calling any handlers 
> > > present at each frame (which all have a different calling convention from 
> > > Itanium handlers), and handling chained unwind info... Or we could use 
> > > the implementation that MS provided to us for free--and which gets loaded 
> > > into every process anyway by virtue of being in NTDLL, and which is 
> > > extremely well tested. Given all that, I'm wondering what implementing 
> > > all that ourselves would gain us. I suppose we could eventually do all 
> > > that, but for now, I think this is outside the scope of my change.
> >
> >
> > +1. I guess such a library would be very nice to have, but from the point 
> > of view of implementing exception handling, using the underlying APIs 
> > probably is the way to go. The other question, as posted before, is whether 
> > we want to wrap the whole CONTEXT structs in the UnwindCursor class and 
> > expose it via the unw_* set of APIs. It gives quite a significant amount of 
> > extra code here compared to libgcc's unwind-seh.c which is <500 loc 
> > altogether, providing only the _Unwind_* API, implementing it directly with 
> > the Windows Rtl* APIs from ntdll. That would give only a partial libunwind, 
> > with only the higher level API available, but that's the only part used for 
> > exception handling at least.
>
>
> That still makes the underlying assumption that SEH is exclusive to Windows 
> (and by that virtue PE/COFF) which doesn't necessarily hold true. There is 
> also the issue of generic names like `_LIBUNWIND_SUPPORT_SEH_UNWIND` to guard 
> includes of Windows specific headers which ties into my previous point. Would 
> it be possible to somehow abstract away the Windows runtime function call and 
> Windows specific header includes, even if it's via CMake options.
>
> I'm raising this issue as there are other implementations of SEH that share 
> the same (or extremely similar, depending on SDK versions) structures, but 
> would not have the Windows headers available when compiling libunwind, and 
> while the runtime function call to the `Rtl*` API is easy to change later on, 
> separating rest of it from Windows headers is slightly messier.
>
> Would it, at very least, be possible to decouple most of it from a dependency 
> on Windows headers and if possible use things like `void*` in place of 
> `PVOID` or anything that's `stdint.h/inttypes.h` friendly? It's an excellent 
> patch regardless but loosening the Windows SDK dependencies a bit would make 
> it a lot better.
>
> Would be much appreciated, as I'm going through a backlog of patches I'd like 
> to put up for review one of which includes SEH for x86_64 Linux (ELF) 
> implemented using RT signals and additional compiler runtime glue code, 
> currently residing within compiler-rt builtins (one of the issues I want to 
> address before). It's quite a wonky ABI since I tried to keep as much 
> compatible with 64-bit Windows SEH (`.xdata` variation) in terms of frame 
> lowering etc, but run-time mechanisms differ vastly for obvious reasons. 
> Having it interop with libunwind smoothly without rewriting much of existing 
> code in this patch would be nice, or even worse resorting to a million 
> preprocessor guards to cover all the cases.


Very well, then. I'll see what I can do.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-21 Thread Kristina Brooks via Phabricator via cfe-commits
kristina added a comment.

In https://reviews.llvm.org/D50564#1206393, @mstorsjo wrote:

> In https://reviews.llvm.org/D50564#1206370, @cdavis5x wrote:
>
> > In https://reviews.llvm.org/D50564#1206302, @kristina wrote:
> >
> > > I'm all for this change except the core issue is that you're using 
> > > libunwind as a shim around the actual unwinding API provided by Windows. 
> > > It would be nice to have something that did not have to do that and was 
> > > capable of performing unwinding of SEH-style exceptions without needing 
> > > additional runtime support.
> >
> >
> > It would be nice, but that would require extra work. We'd have to implement 
> > reading and interpreting unwind codes, and calling any handlers present at 
> > each frame (which all have a different calling convention from Itanium 
> > handlers), and handling chained unwind info... Or we could use the 
> > implementation that MS provided to us for free--and which gets loaded into 
> > every process anyway by virtue of being in NTDLL, and which is extremely 
> > well tested. Given all that, I'm wondering what implementing all that 
> > ourselves would gain us. I suppose we could eventually do all that, but for 
> > now, I think this is outside the scope of my change.
>
>
> +1. I guess such a library would be very nice to have, but from the point of 
> view of implementing exception handling, using the underlying APIs probably 
> is the way to go. The other question, as posted before, is whether we want to 
> wrap the whole CONTEXT structs in the UnwindCursor class and expose it via 
> the unw_* set of APIs. It gives quite a significant amount of extra code here 
> compared to libgcc's unwind-seh.c which is <500 loc altogether, providing 
> only the _Unwind_* API, implementing it directly with the Windows Rtl* APIs 
> from ntdll. That would give only a partial libunwind, with only the higher 
> level API available, but that's the only part used for exception handling at 
> least.


That still makes the underlying assumption that SEH is exclusive to Windows 
(and by that virtue PE/COFF) which doesn't necessarily hold true. There is also 
the issue of generic names like `_LIBUNWIND_SUPPORT_SEH_UNWIND` to guard 
includes of Windows specific headers which ties into my previous point. Would 
it be possible to somehow abstract away the Windows runtime function call and 
Windows specific header includes, even if it's via CMake options.

I'm raising this issue as there are other implementations of SEH that share the 
same (or extremely similar, depending on SDK versions) structures, but would 
not have the Windows headers available when compiling libunwind, and while the 
runtime function call to the `Rtl*` API is easy to change later on, separating 
rest of it from Windows headers is slightly messier.

Would it, at very least, be possible to decouple most of it from a dependency 
on Windows headers?

Would be much appreciated, as I'm going through a backlog of patches I'd like 
to put up for review one of which includes SEH for x86_64 Linux (ELF) 
implemented using RT signals and additional compiler runtime glue code, 
currently residing within compiler-rt builtins (one of the issues I want to 
address before). It's quite a wonky ABI since I tried to keep as much 
compatible with 64-bit Windows SEH (`.xdata` variation) in terms of frame 
lowering etc, but run-time mechanisms differ vastly for obvious reasons.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-20 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo added a comment.

In https://reviews.llvm.org/D50564#1206370, @cdavis5x wrote:

> In https://reviews.llvm.org/D50564#1206302, @kristina wrote:
>
> > I'm all for this change except the core issue is that you're using 
> > libunwind as a shim around the actual unwinding API provided by Windows. It 
> > would be nice to have something that did not have to do that and was 
> > capable of performing unwinding of SEH-style exceptions without needing 
> > additional runtime support.
>
>
> It would be nice, but that would require extra work. We'd have to implement 
> reading and interpreting unwind codes, and calling any handlers present at 
> each frame (which all have a different calling convention from Itanium 
> handlers), and handling chained unwind info... Or we could use the 
> implementation that MS provided to us for free--and which gets loaded into 
> every process anyway by virtue of being in NTDLL, and which is extremely well 
> tested. Given all that, I'm wondering what implementing all that ourselves 
> would gain us. I suppose we could eventually do all that, but for now, I 
> think this is outside the scope of my change.


+1. I guess such a library would be very nice to have, but from the point of 
view of implementing exception handling, using the underlying APIs probably is 
the way to go. The other question, as posted before, is whether we want to wrap 
the whole CONTEXT structs in the UnwindCursor class and expose it via the unw_* 
set of APIs. It gives quite a significant amount of extra code here compared to 
libgcc's unwind-seh.c which is <500 loc altogether, providing only the 
_Unwind_* API, implementing it directly with the Windows Rtl* APIs from ntdll. 
That would give only a partial libunwind, with only the higher level API 
available, but that's the only part used for exception handling at least.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-20 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x added a comment.

In https://reviews.llvm.org/D50564#1206302, @kristina wrote:

> I'm all for this change except the core issue is that you're using libunwind 
> as a shim around the actual unwinding API provided by Windows. It would be 
> nice to have something that did not have to do that and was capable of 
> performing unwinding of SEH-style exceptions without needing additional 
> runtime support.


It would be nice, but that would require extra work. We'd have to implement 
reading and interpreting unwind codes, and calling any handlers present at each 
frame (which all have a different calling convention from Itanium handlers), 
and handling chained unwind info... Or we could use the implementation that MS 
provided to us for free--and which gets loaded into every process anyway by 
virtue of being in NTDLL, and which is extremely well tested. Given all that, 
I'm wondering what implementing all that ourselves would gain us. I suppose we 
could eventually do all that, but for now, I think this is outside the scope of 
my change.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-20 Thread Kristina Brooks via Phabricator via cfe-commits
kristina added a comment.

I'm all for this change except the core issue is that you're using libunwind as 
a shim around the actual unwinding API provided by Windows. It would be nice to 
have something that did not have to do that and was capable of performing 
unwinding of SEH-style exceptions without needing additional runtime support.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-20 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x added a comment.

Ping...


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-17 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x added a comment.

Ping.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-14 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x updated this revision to Diff 160660.
cdavis5x added a comment.

- Get rid of DISPATCHER_CONTEXT def for ARM. We only support ARM on Win8+ 
anyway.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564

Files:
  include/__libunwind_config.h
  src/AddressSpace.hpp
  src/CMakeLists.txt
  src/Unwind-seh.cpp
  src/UnwindCursor.hpp
  src/UnwindLevel1-gcc-ext.c
  src/UnwindLevel1.c
  src/config.h
  src/libunwind_ext.h

Index: src/libunwind_ext.h
===
--- src/libunwind_ext.h
+++ src/libunwind_ext.h
@@ -17,6 +17,12 @@
 #include 
 #include 
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+  #include 
+  #include 
+  #include 
+#endif
+
 #define UNW_STEP_SUCCESS 1
 #define UNW_STEP_END 0
 
@@ -33,6 +39,28 @@
 extern void _unw_add_dynamic_fde(unw_word_t fde);
 extern void _unw_remove_dynamic_fde(unw_word_t fde);
 
+// Provide a definition for the DISPATCHER_CONTEXT struct for old (Win7 and
+// earlier) SDKs.
+// MinGW-w64 has always provided this struct.
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && !defined(__MINGW32__) && VER_PRODUCTBUILD < 8000
+  #if defined(__x86_64__)
+typedef struct _DISPATCHER_CONTEXT {
+  ULONG64 ControlPc;
+  ULONG64 ImageBase;
+  PRUNTIME_FUNCTION FunctionEntry;
+  ULONG64 EstablisherFrame;
+  ULONG64 TargetIp;
+  PCONTEXT ContextRecord;
+  PEXCEPTION_ROUTINE LanguageHandler;
+  PVOID HandlerData;
+  PUNWIND_HISTORY_TABLE HistoryTable;
+  ULONG ScopeIndex;
+  ULONG Fill0;
+} DISPATCHER_CONTEXT;
+  #endif
+typedef DISPATCHER_CONTEXT* PDISPATCHER_CONTEXT;
+#endif
+
 #if defined(_LIBUNWIND_ARM_EHABI)
 extern const uint32_t* decode_eht_entry(const uint32_t*, size_t*, size_t*);
 extern _Unwind_Reason_Code _Unwind_VRS_Interpret(_Unwind_Context *context,
Index: src/config.h
===
--- src/config.h
+++ src/config.h
@@ -38,7 +38,11 @@
 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND   1
   #endif
 #elif defined(_WIN32)
-  #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
+  #ifdef __SEH__
+#define _LIBUNWIND_SUPPORT_SEH_UNWIND 1
+  #else
+#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
+  #endif
 #else
   #if defined(__ARM_DWARF_EH__) || !defined(__arm__)
 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
Index: src/UnwindLevel1.c
===
--- src/UnwindLevel1.c
+++ src/UnwindLevel1.c
@@ -32,6 +32,8 @@
 
 #if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__)
 
+#ifndef _LIBUNWIND_SUPPORT_SEH_UNWIND
+
 static _Unwind_Reason_Code
 unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
   unw_init_local(cursor, uc);
@@ -449,6 +451,7 @@
   return result;
 }
 
+#endif // !_LIBUNWIND_SUPPORT_SEH_UNWIND
 
 /// Called by personality handler during phase 2 if a foreign exception
 // is caught.
Index: src/UnwindLevel1-gcc-ext.c
===
--- src/UnwindLevel1-gcc-ext.c
+++ src/UnwindLevel1-gcc-ext.c
@@ -25,6 +25,10 @@
 
 #if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+#define private_1 private_[0]
+#endif
+
 ///  Called by __cxa_rethrow().
 _LIBUNWIND_EXPORT _Unwind_Reason_Code
 _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) {
Index: src/UnwindCursor.hpp
===
--- src/UnwindCursor.hpp
+++ src/UnwindCursor.hpp
@@ -18,18 +18,40 @@
 #include 
 #include 
 
+#ifdef _WIN32
+  #include 
+#endif
 #ifdef __APPLE__
   #include 
 #endif
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+#  ifdef _LIBUNWIND_TARGET_X86_64
+struct UNWIND_INFO {
+  BYTE Version : 3;
+  BYTE Flags : 5;
+  BYTE SizeOfProlog;
+  BYTE CountOfCodes;
+  BYTE FrameRegister : 4;
+  BYTE FrameOffset : 4;
+  WORD UnwindCodes[2];
+};
+#  endif
+
+extern "C" _Unwind_Reason_Code __libunwind_seh_personality(
+int, _Unwind_Action, _Unwind_Exception_Class, _Unwind_Exception *,
+struct _Unwind_Context *);
+
+#endif
+
 #include "config.h"
 
 #include "AddressSpace.hpp"
 #include "CompactUnwinder.hpp"
 #include "config.h"
 #include "DwarfInstructions.hpp"
 #include "EHHeaderParser.hpp"
-#include "libunwind.h"
+#include "libunwind_ext.h"
 #include "Registers.hpp"
 #include "RWMutex.hpp"
 #include "Unwind-EHABI.h"
@@ -412,6 +434,525 @@
 #endif
 };
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+
+/// \c UnwindCursor contains all state (including all register values) during
+/// an unwind.  This is normally stack-allocated inside a unw_cursor_t.
+template 
+class UnwindCursor : public AbstractUnwindCursor {
+  typedef typename A::pint_t pint_t;
+public:
+  UnwindCursor(unw_context_t *context, A &as);
+  UnwindCursor(CONTEXT *context, A &as);
+  UnwindCursor(A &as, void *threadArg);
+  virtual ~UnwindCursor() {}
+  virtual boolvalidReg(int);
+  virtual unw_wor

[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-14 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x added a comment.

...And it turns out Phab marked the comments as done when I uploaded the new 
change. I didn't know it would do that. That's useful to know.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-14 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x added a comment.

Marked some comments as done. (Phab won't let me post an empty comment, so...)


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-14 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x updated this revision to Diff 160638.
cdavis5x marked 3 inline comments as done.
cdavis5x edited the summary of this revision.
cdavis5x added a comment.

- Update checks for DISPATCHER_CONTEXT definition.
- Add link to KJK::Hyperion's articles on SEH.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564

Files:
  include/__libunwind_config.h
  src/AddressSpace.hpp
  src/CMakeLists.txt
  src/Unwind-seh.cpp
  src/UnwindCursor.hpp
  src/UnwindLevel1-gcc-ext.c
  src/UnwindLevel1.c
  src/config.h
  src/libunwind_ext.h

Index: src/libunwind_ext.h
===
--- src/libunwind_ext.h
+++ src/libunwind_ext.h
@@ -17,6 +17,12 @@
 #include 
 #include 
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+  #include 
+  #include 
+  #include 
+#endif
+
 #define UNW_STEP_SUCCESS 1
 #define UNW_STEP_END 0
 
@@ -33,6 +39,44 @@
 extern void _unw_add_dynamic_fde(unw_word_t fde);
 extern void _unw_remove_dynamic_fde(unw_word_t fde);
 
+// Provide a definition for the DISPATCHER_CONTEXT struct for old (Win7 and
+// earlier) SDKs.
+// MinGW-w64 has always provided this struct.
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && !defined(__MINGW32__) && VER_PRODUCTBUILD < 8000
+  #if defined(__x86_64__)
+typedef struct _DISPATCHER_CONTEXT {
+  ULONG64 ControlPc;
+  ULONG64 ImageBase;
+  PRUNTIME_FUNCTION FunctionEntry;
+  ULONG64 EstablisherFrame;
+  ULONG64 TargetIp;
+  PCONTEXT ContextRecord;
+  PEXCEPTION_ROUTINE LanguageHandler;
+  PVOID HandlerData;
+  PUNWIND_HISTORY_TABLE HistoryTable;
+  ULONG ScopeIndex;
+  ULONG Fill0;
+} DISPATCHER_CONTEXT;
+  #elif defined(__arm__)
+typedef struct _DISPATCHER_CONTEXT {
+  ULONG ControlPc;
+  ULONG ImageBase;
+  PRUNTIME_FUNCTION FunctionEntry;
+  ULONG EstablisherFrame;
+  ULONG TargetIp;
+  PCONTEXT ContextRecord;
+  PEXCEPTION_ROUTINE LanguageHandler;
+  PVOID HandlerData;
+  PUNWIND_HISTORY_TABLE HistoryTable;
+  ULONG ScopeIndex;
+  ULONG ControlPcIsUnwound;
+  PKNONVOLATILE_CONTEXT_POINTERS NonVolatileRegisters;
+  ULONG VirtualVfpHead;
+} DISPATCHER_CONTEXT;
+  #endif
+typedef DISPATCHER_CONTEXT* PDISPATCHER_CONTEXT;
+#endif
+
 #if defined(_LIBUNWIND_ARM_EHABI)
 extern const uint32_t* decode_eht_entry(const uint32_t*, size_t*, size_t*);
 extern _Unwind_Reason_Code _Unwind_VRS_Interpret(_Unwind_Context *context,
Index: src/config.h
===
--- src/config.h
+++ src/config.h
@@ -38,7 +38,11 @@
 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND   1
   #endif
 #elif defined(_WIN32)
-  #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
+  #ifdef __SEH__
+#define _LIBUNWIND_SUPPORT_SEH_UNWIND 1
+  #else
+#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
+  #endif
 #else
   #if defined(__ARM_DWARF_EH__) || !defined(__arm__)
 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
Index: src/UnwindLevel1.c
===
--- src/UnwindLevel1.c
+++ src/UnwindLevel1.c
@@ -32,6 +32,8 @@
 
 #if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__)
 
+#ifndef _LIBUNWIND_SUPPORT_SEH_UNWIND
+
 static _Unwind_Reason_Code
 unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
   unw_init_local(cursor, uc);
@@ -449,6 +451,7 @@
   return result;
 }
 
+#endif // !_LIBUNWIND_SUPPORT_SEH_UNWIND
 
 /// Called by personality handler during phase 2 if a foreign exception
 // is caught.
Index: src/UnwindLevel1-gcc-ext.c
===
--- src/UnwindLevel1-gcc-ext.c
+++ src/UnwindLevel1-gcc-ext.c
@@ -25,6 +25,10 @@
 
 #if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+#define private_1 private_[0]
+#endif
+
 ///  Called by __cxa_rethrow().
 _LIBUNWIND_EXPORT _Unwind_Reason_Code
 _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) {
Index: src/UnwindCursor.hpp
===
--- src/UnwindCursor.hpp
+++ src/UnwindCursor.hpp
@@ -18,18 +18,40 @@
 #include 
 #include 
 
+#ifdef _WIN32
+  #include 
+#endif
 #ifdef __APPLE__
   #include 
 #endif
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+#  ifdef _LIBUNWIND_TARGET_X86_64
+struct UNWIND_INFO {
+  BYTE Version : 3;
+  BYTE Flags : 5;
+  BYTE SizeOfProlog;
+  BYTE CountOfCodes;
+  BYTE FrameRegister : 4;
+  BYTE FrameOffset : 4;
+  WORD UnwindCodes[2];
+};
+#  endif
+
+extern "C" _Unwind_Reason_Code __libunwind_seh_personality(
+int, _Unwind_Action, _Unwind_Exception_Class, _Unwind_Exception *,
+struct _Unwind_Context *);
+
+#endif
+
 #include "config.h"
 
 #include "AddressSpace.hpp"
 #include "CompactUnwinder.hpp"
 #include "config.h"
 #include "DwarfInstructions.hpp"
 #include "EHHeaderParser.hpp"
-#include "libunwind.h"
+#include "libunwind_ext.h"
 #include "Registers.hpp"
 #include "RWMutex.hpp"
 #include "Unwind-EHABI.h"
@@ -412,6 +434,525 @@
 #endif
 };
 
+#if defined(_LIBUNWIND_SU

[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-14 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x added a comment.

In https://reviews.llvm.org/D50564#1195985, @cdavis5x wrote:

> In https://reviews.llvm.org/D50564#1195794, @mstorsjo wrote:
>
> > > Special thanks to KJK::Hyperion for his excellent series of articles on 
> > > how EH works on x86-64 Windows. (Seriously, check it out. It's awesome.)
> >
> > Can you give some links to it? A brief googling didn't turn up much else 
> > than the PSEH library.
>
>
> I can't seem to find it either. I wonder if it's vanished from the Internet. 
> Maybe the IA will have something.


Found it: http://www.nynaeve.net/?p=99. Interestingly, a reference to that was 
in the MinGW headers--I think that's how I found it in the first place. I'll 
update the description.

In https://reviews.llvm.org/D50564#1199311, @zturner wrote:

> In https://reviews.llvm.org/D50564#1199285, @rnk wrote:
>
> > In https://reviews.llvm.org/D50564#1198996, @cdavis5x wrote:
> >
> > > Could somebody verify that the `DISPATCHER_CONTEXT` struct is defined in 
> > > `` for the Win8 and Win10 SDKs? I can't install them right now.
> >
> >
> > I checked both, and they are available, so I think we should guard the 
> > definition like this:
> >
> >   // Provide a definition for _DISPATCHER_CONTEXT for Win7 and earlier SDK 
> > versions.
> >   // Mingw64 has always provided this struct.
> >   #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && !defined(__MINGW64__) && 
> > defined(WINVER) && WINVER < _WIN32_WINNT_WIN8
> >   # if defined(__x86_64__)
> >   typedef struct _DISPATCHER_CONTEXT { ... } DISPATCHER_CONTEXT;
> >   # elif defined(__arm__)
> >   typedef struct _DISPATCHER_CONTEXT { ... } DISPATCHER_CONTEXT;
> >   # endif
> >   #endif
> >
> >
> > Does that seem right? I'm not super familiar with SDK version detection, so 
> > I might have the wrong macros.
>
>
> I believe you need to check `VER_PRODUCTBUILD` from `` if you are 
> looking for the version of the Windows SDK that is being used to build the 
> current application.


Thanks, @rnk and @zturner.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-14 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo added a comment.

In https://reviews.llvm.org/D50564#1199285, @rnk wrote:

> In https://reviews.llvm.org/D50564#1198996, @cdavis5x wrote:
>
> > Could somebody verify that the `DISPATCHER_CONTEXT` struct is defined in 
> > `` for the Win8 and Win10 SDKs? I can't install them right now.
>
>
> I checked both, and they are available, so I think we should guard the 
> definition like this:
>
>   // Provide a definition for _DISPATCHER_CONTEXT for Win7 and earlier SDK 
> versions.
>   // Mingw64 has always provided this struct.
>   #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && !defined(__MINGW64__) && 
> defined(WINVER) && WINVER < _WIN32_WINNT_WIN8


For the mingw check, I'd prefer checking for `__MINGW32__`, as the -64 version 
isn't defined when targeting 32 bit ARM (which uses SEH, even though everything 
isn't in place for it in LLVM).

And mingw-w64 might lack this struct for arm/arm64, but I can fix that and 
wouldn't bother with older versions of that.

And if these structs only are added for compat with the win7 sdk, maybe omit 
the arm one altogether, as all modern non-windows ce versions on arm is >= win8.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-14 Thread Zachary Turner via Phabricator via cfe-commits
zturner added a comment.

In https://reviews.llvm.org/D50564#1199285, @rnk wrote:

> In https://reviews.llvm.org/D50564#1198996, @cdavis5x wrote:
>
> > Could somebody verify that the `DISPATCHER_CONTEXT` struct is defined in 
> > `` for the Win8 and Win10 SDKs? I can't install them right now.
>
>
> I checked both, and they are available, so I think we should guard the 
> definition like this:
>
>   // Provide a definition for _DISPATCHER_CONTEXT for Win7 and earlier SDK 
> versions.
>   // Mingw64 has always provided this struct.
>   #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && !defined(__MINGW64__) && 
> defined(WINVER) && WINVER < _WIN32_WINNT_WIN8
>   # if defined(__x86_64__)
>   typedef struct _DISPATCHER_CONTEXT { ... } DISPATCHER_CONTEXT;
>   # elif defined(__arm__)
>   typedef struct _DISPATCHER_CONTEXT { ... } DISPATCHER_CONTEXT;
>   # endif
>   #endif
>
>
> Does that seem right? I'm not super familiar with SDK version detection, so I 
> might have the wrong macros.


I believe you need to check `VER_PRODUCTBUILD` from `` if you are 
looking for the version of the Windows SDK that is being used to build the 
current application.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-14 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added a comment.

In https://reviews.llvm.org/D50564#1198996, @cdavis5x wrote:

> Could somebody verify that the `DISPATCHER_CONTEXT` struct is defined in 
> `` for the Win8 and Win10 SDKs? I can't install them right now.


I checked both, and they are available, so I think we should guard the 
definition like this:

  // Provide a definition for _DISPATCHER_CONTEXT for Win7 and earlier SDK 
versions.
  // Mingw64 has always provided this struct.
  #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND) && !defined(__MINGW64__) && 
defined(WINVER) && WINVER < _WIN32_WINNT_WIN8
  # if defined(__x86_64__)
  typedef struct _DISPATCHER_CONTEXT { ... } DISPATCHER_CONTEXT;
  # elif defined(__arm__)
  typedef struct _DISPATCHER_CONTEXT { ... } DISPATCHER_CONTEXT;
  # endif
  #endif

Does that seem right? I'm not super familiar with SDK version detection, so I 
might have the wrong macros.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-14 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x added a comment.

Could somebody verify that the `DISPATCHER_CONTEXT` struct is defined in 
`` for the Win8 and Win10 SDKs? I can't install them right now.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-10 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added inline comments.



Comment at: src/libunwind_ext.h:43
+  #if defined(__x86_64__) && !defined(__MINGW64__)
+typedef struct _DISPATCHER_CONTEXT {
+  ULONG64 ControlPc;

cdavis5x wrote:
> mstorsjo wrote:
> > What's this all about? winnt.h (from both MSVC and mingw-w64) should define 
> > this struct, no?
> Not my copy of `` from the Win7 SDK. Dunno about WIn8 and WIn10.
If we have to pick between SDK versions to support, I'd much prefer to support 
8+.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-10 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x added a comment.

In https://reviews.llvm.org/D50564#1195794, @mstorsjo wrote:

> > Special thanks to KJK::Hyperion for his excellent series of articles on how 
> > EH works on x86-64 Windows. (Seriously, check it out. It's awesome.)
>
> Can you give some links to it? A brief googling didn't turn up much else than 
> the PSEH library.


I can't seem to find it either. I wonder if it's vanished from the Internet. 
Maybe the IA will have something.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-10 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x updated this revision to Diff 160195.
cdavis5x added a comment.

- Fix outdated comment.
- Make preprocessor conditional more consistent.
- Make some private functions used only in a single file static.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564

Files:
  include/__libunwind_config.h
  src/AddressSpace.hpp
  src/CMakeLists.txt
  src/Unwind-seh.cpp
  src/UnwindCursor.hpp
  src/UnwindLevel1-gcc-ext.c
  src/UnwindLevel1.c
  src/config.h
  src/libunwind_ext.h

Index: src/libunwind_ext.h
===
--- src/libunwind_ext.h
+++ src/libunwind_ext.h
@@ -17,6 +17,11 @@
 #include 
 #include 
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+  #include 
+  #include 
+#endif
+
 #define UNW_STEP_SUCCESS 1
 #define UNW_STEP_END 0
 
@@ -33,6 +38,40 @@
 extern void _unw_add_dynamic_fde(unw_word_t fde);
 extern void _unw_remove_dynamic_fde(unw_word_t fde);
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+  #if defined(__x86_64__) && !defined(__MINGW64__)
+typedef struct _DISPATCHER_CONTEXT {
+  ULONG64 ControlPc;
+  ULONG64 ImageBase;
+  PRUNTIME_FUNCTION FunctionEntry;
+  ULONG64 EstablisherFrame;
+  ULONG64 TargetIp;
+  PCONTEXT ContextRecord;
+  PEXCEPTION_ROUTINE LanguageHandler;
+  PVOID HandlerData;
+  PUNWIND_HISTORY_TABLE HistoryTable;
+  ULONG ScopeIndex;
+  ULONG Fill0;
+} DISPATCHER_CONTEXT;
+  #elif defined(__arm__)
+typedef struct _DISPATCHER_CONTEXT {
+  ULONG ControlPc;
+  ULONG ImageBase;
+  PRUNTIME_FUNCTION FunctionEntry;
+  ULONG EstablisherFrame;
+  ULONG TargetIp;
+  PCONTEXT ContextRecord;
+  PEXCEPTION_ROUTINE LanguageHandler;
+  PVOID HandlerData;
+  PUNWIND_HISTORY_TABLE HistoryTable;
+  ULONG ScopeIndex;
+  ULONG ControlPcIsUnwound;
+  PKNONVOLATILE_CONTEXT_POINTERS NonVolatileRegisters;
+  ULONG VirtualVfpHead;
+} DISPATCHER_CONTEXT;
+  #endif
+#endif
+
 #if defined(_LIBUNWIND_ARM_EHABI)
 extern const uint32_t* decode_eht_entry(const uint32_t*, size_t*, size_t*);
 extern _Unwind_Reason_Code _Unwind_VRS_Interpret(_Unwind_Context *context,
Index: src/config.h
===
--- src/config.h
+++ src/config.h
@@ -38,7 +38,11 @@
 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND   1
   #endif
 #elif defined(_WIN32)
-  #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
+  #ifdef __SEH__
+#define _LIBUNWIND_SUPPORT_SEH_UNWIND 1
+  #else
+#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
+  #endif
 #else
   #if defined(__ARM_DWARF_EH__) || !defined(__arm__)
 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
Index: src/UnwindLevel1.c
===
--- src/UnwindLevel1.c
+++ src/UnwindLevel1.c
@@ -32,6 +32,8 @@
 
 #if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__)
 
+#ifndef _LIBUNWIND_SUPPORT_SEH_UNWIND
+
 static _Unwind_Reason_Code
 unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
   unw_init_local(cursor, uc);
@@ -449,6 +451,7 @@
   return result;
 }
 
+#endif // !_LIBUNWIND_SUPPORT_SEH_UNWIND
 
 /// Called by personality handler during phase 2 if a foreign exception
 // is caught.
Index: src/UnwindLevel1-gcc-ext.c
===
--- src/UnwindLevel1-gcc-ext.c
+++ src/UnwindLevel1-gcc-ext.c
@@ -25,6 +25,10 @@
 
 #if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+#define private_1 private_[0]
+#endif
+
 ///  Called by __cxa_rethrow().
 _LIBUNWIND_EXPORT _Unwind_Reason_Code
 _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) {
Index: src/UnwindCursor.hpp
===
--- src/UnwindCursor.hpp
+++ src/UnwindCursor.hpp
@@ -18,18 +18,40 @@
 #include 
 #include 
 
+#ifdef _WIN32
+  #include 
+#endif
 #ifdef __APPLE__
   #include 
 #endif
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+#  ifdef _LIBUNWIND_TARGET_X86_64
+struct UNWIND_INFO {
+  BYTE Version : 3;
+  BYTE Flags : 5;
+  BYTE SizeOfProlog;
+  BYTE CountOfCodes;
+  BYTE FrameRegister : 4;
+  BYTE FrameOffset : 4;
+  WORD UnwindCodes[2];
+};
+#  endif
+
+extern "C" _Unwind_Reason_Code __libunwind_seh_personality(
+int, _Unwind_Action, _Unwind_Exception_Class, _Unwind_Exception *,
+struct _Unwind_Context *);
+
+#endif
+
 #include "config.h"
 
 #include "AddressSpace.hpp"
 #include "CompactUnwinder.hpp"
 #include "config.h"
 #include "DwarfInstructions.hpp"
 #include "EHHeaderParser.hpp"
-#include "libunwind.h"
+#include "libunwind_ext.h"
 #include "Registers.hpp"
 #include "RWMutex.hpp"
 #include "Unwind-EHABI.h"
@@ -412,6 +434,525 @@
 #endif
 };
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+
+/// \c UnwindCursor contains all state (including all register values) during
+/// an unwind.  This is normally stack-allocated inside a unw_cursor_t.
+template 
+class UnwindCursor : public AbstractUnwindCursor {
+  typedef typename A::pint_t pint_t;
+public:

[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-10 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x added inline comments.



Comment at: src/Unwind-seh.cpp:53
+
+/// Exception cleanup routine used by \c __libunwind_frame_consolidate to
+/// regain control after handling an SEH exception.

mstorsjo wrote:
> I don't see any `__libunwind_frame_consolidate` anywhere, is this comment 
> outdated?
Why yes it is.



Comment at: src/UnwindLevel1.c:35
 
+#if !_LIBUNWIND_SUPPORT_SEH_UNWIND
+

mstorsjo wrote:
> This probably works, but isn't `#if !defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)` 
> more of the common form?
I think I wrote this before the change to make that so took place, and I forgot 
to update this. Good catch.



Comment at: src/libunwind_ext.h:73
+  #endif
+extern int _unw_init_seh(unw_cursor_t *cursor, CONTEXT *ctx);
+extern DISPATCHER_CONTEXT *_unw_seh_get_disp_ctx(unw_cursor_t *cursor);

mstorsjo wrote:
> These are all both defined and called from Unwind-seh.cpp, so couldn't they 
> just be static functions within there?
Probably. Done.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-10 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x added inline comments.



Comment at: src/libunwind_ext.h:43
+  #if defined(__x86_64__) && !defined(__MINGW64__)
+typedef struct _DISPATCHER_CONTEXT {
+  ULONG64 ControlPc;

mstorsjo wrote:
> What's this all about? winnt.h (from both MSVC and mingw-w64) should define 
> this struct, no?
Not my copy of `` from the Win7 SDK. Dunno about WIn8 and WIn10.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-10 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo added a comment.

> I've tested this implementation on x86-64 to ensure that it works. All 
> libc++abi tests pass, as do all libc++ exception-related tests.

I tested it now as well, and seems to work for my simple testcase.

> ARM still remains to be implemented (@compnerd?).

LLVM doesn't generate SEH unwind data for ARM at all yet. ARM64 implementation 
is ongoing at the moment though, see https://reviews.llvm.org/D50166 and 
https://reviews.llvm.org/D50288.

> Special thanks to KJK::Hyperion for his excellent series of articles on how 
> EH works on x86-64 Windows. (Seriously, check it out. It's awesome.)

Can you give some links to it? A brief googling didn't turn up much else than 
the PSEH library.

> I'm actually not sure if this should go in as is. I particularly don't like 
> that I duplicated the UnwindCursor class for this special case.

As I'm not totally familiar with how it works, I can only give cursory comments 
and compare to the libgcc implementation when trying to wrap my head around it, 
but this does seem way, way more complex than the libgcc version of the same.

As for the duplicated UnwindCursor, I'm thinking if it'd become more 
straightforward by avoiding touching those parts altogether, and just 
reimplementing all the other public functions, `_Unwind_G/SetGR/IP`, 
`_Unwind_Backtrace` etc, directly in Unwind-seh.cpp, and not care about using 
the libunwind.h APIs (`unw_*`) inbetween altogether? Or perhaps my libgcc 
comparison is making me biased.




Comment at: src/Unwind-seh.cpp:53
+
+/// Exception cleanup routine used by \c __libunwind_frame_consolidate to
+/// regain control after handling an SEH exception.

I don't see any `__libunwind_frame_consolidate` anywhere, is this comment 
outdated?



Comment at: src/UnwindLevel1.c:35
 
+#if !_LIBUNWIND_SUPPORT_SEH_UNWIND
+

This probably works, but isn't `#if !defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)` 
more of the common form?



Comment at: src/libunwind_ext.h:43
+  #if defined(__x86_64__) && !defined(__MINGW64__)
+typedef struct _DISPATCHER_CONTEXT {
+  ULONG64 ControlPc;

What's this all about? winnt.h (from both MSVC and mingw-w64) should define 
this struct, no?



Comment at: src/libunwind_ext.h:73
+  #endif
+extern int _unw_init_seh(unw_cursor_t *cursor, CONTEXT *ctx);
+extern DISPATCHER_CONTEXT *_unw_seh_get_disp_ctx(unw_cursor_t *cursor);

These are all both defined and called from Unwind-seh.cpp, so couldn't they 
just be static functions within there?


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50564: Add support for SEH unwinding on Windows.

2018-08-10 Thread Charles Davis via Phabricator via cfe-commits
cdavis5x created this revision.
cdavis5x added reviewers: mstorsjo, rnk, compnerd, smeenai.
Herald added subscribers: cfe-commits, chrib, christof, kristof.beyls, mgorny.
Herald added a reviewer: javed.absar.

I've tested this implementation on x86-64 to ensure that it works. All
`libc++abi` tests pass, as do all `libc++` exception-related tests. ARM
still remains to be implemented (@compnerd?).

Special thanks to KJK::Hyperion for his excellent series of articles on
how EH works on x86-64 Windows. (Seriously, check it out. It's awesome.)

I'm actually not sure if this should go in as is. I particularly don't
like that I duplicated the UnwindCursor class for this special case.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D50564

Files:
  include/__libunwind_config.h
  src/AddressSpace.hpp
  src/CMakeLists.txt
  src/Unwind-seh.cpp
  src/UnwindCursor.hpp
  src/UnwindLevel1-gcc-ext.c
  src/UnwindLevel1.c
  src/config.h
  src/libunwind_ext.h

Index: src/libunwind_ext.h
===
--- src/libunwind_ext.h
+++ src/libunwind_ext.h
@@ -17,6 +17,11 @@
 #include 
 #include 
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+  #include 
+  #include 
+#endif
+
 #define UNW_STEP_SUCCESS 1
 #define UNW_STEP_END 0
 
@@ -33,6 +38,43 @@
 extern void _unw_add_dynamic_fde(unw_word_t fde);
 extern void _unw_remove_dynamic_fde(unw_word_t fde);
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+  #if defined(__x86_64__) && !defined(__MINGW64__)
+typedef struct _DISPATCHER_CONTEXT {
+  ULONG64 ControlPc;
+  ULONG64 ImageBase;
+  PRUNTIME_FUNCTION FunctionEntry;
+  ULONG64 EstablisherFrame;
+  ULONG64 TargetIp;
+  PCONTEXT ContextRecord;
+  PEXCEPTION_ROUTINE LanguageHandler;
+  PVOID HandlerData;
+  PUNWIND_HISTORY_TABLE HistoryTable;
+  ULONG ScopeIndex;
+  ULONG Fill0;
+} DISPATCHER_CONTEXT;
+  #elif defined(__arm__)
+typedef struct _DISPATCHER_CONTEXT {
+  ULONG ControlPc;
+  ULONG ImageBase;
+  PRUNTIME_FUNCTION FunctionEntry;
+  ULONG EstablisherFrame;
+  ULONG TargetIp;
+  PCONTEXT ContextRecord;
+  PEXCEPTION_ROUTINE LanguageHandler;
+  PVOID HandlerData;
+  PUNWIND_HISTORY_TABLE HistoryTable;
+  ULONG ScopeIndex;
+  ULONG ControlPcIsUnwound;
+  PKNONVOLATILE_CONTEXT_POINTERS NonVolatileRegisters;
+  ULONG VirtualVfpHead;
+} DISPATCHER_CONTEXT;
+  #endif
+extern int _unw_init_seh(unw_cursor_t *cursor, CONTEXT *ctx);
+extern DISPATCHER_CONTEXT *_unw_seh_get_disp_ctx(unw_cursor_t *cursor);
+extern void _unw_seh_set_disp_ctx(unw_cursor_t *cursor, DISPATCHER_CONTEXT *disp);
+#endif
+
 #if defined(_LIBUNWIND_ARM_EHABI)
 extern const uint32_t* decode_eht_entry(const uint32_t*, size_t*, size_t*);
 extern _Unwind_Reason_Code _Unwind_VRS_Interpret(_Unwind_Context *context,
Index: src/config.h
===
--- src/config.h
+++ src/config.h
@@ -38,7 +38,11 @@
 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND   1
   #endif
 #elif defined(_WIN32)
-  #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
+  #ifdef __SEH__
+#define _LIBUNWIND_SUPPORT_SEH_UNWIND 1
+  #else
+#define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
+  #endif
 #else
   #if defined(__ARM_DWARF_EH__) || !defined(__arm__)
 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
Index: src/UnwindLevel1.c
===
--- src/UnwindLevel1.c
+++ src/UnwindLevel1.c
@@ -32,6 +32,8 @@
 
 #if !defined(_LIBUNWIND_ARM_EHABI) && !defined(__USING_SJLJ_EXCEPTIONS__)
 
+#if !_LIBUNWIND_SUPPORT_SEH_UNWIND
+
 static _Unwind_Reason_Code
 unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
   unw_init_local(cursor, uc);
@@ -449,6 +451,7 @@
   return result;
 }
 
+#endif // !_LIBUNWIND_SUPPORT_SEH_UNWIND
 
 /// Called by personality handler during phase 2 if a foreign exception
 // is caught.
Index: src/UnwindLevel1-gcc-ext.c
===
--- src/UnwindLevel1-gcc-ext.c
+++ src/UnwindLevel1-gcc-ext.c
@@ -25,6 +25,10 @@
 
 #if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+#define private_1 private_[0]
+#endif
+
 ///  Called by __cxa_rethrow().
 _LIBUNWIND_EXPORT _Unwind_Reason_Code
 _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) {
Index: src/UnwindCursor.hpp
===
--- src/UnwindCursor.hpp
+++ src/UnwindCursor.hpp
@@ -18,18 +18,40 @@
 #include 
 #include 
 
+#ifdef _WIN32
+  #include 
+#endif
 #ifdef __APPLE__
   #include 
 #endif
 
+#if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)
+#  ifdef _LIBUNWIND_TARGET_X86_64
+struct UNWIND_INFO {
+  BYTE Version : 3;
+  BYTE Flags : 5;
+  BYTE SizeOfProlog;
+  BYTE CountOfCodes;
+  BYTE FrameRegister : 4;
+  BYTE FrameOffset : 4;
+  WORD UnwindCodes[2];
+};
+#  endif
+
+extern "C" _Unwind_Reason_Code __libunwind_seh_personality(
+int, _Unwind_Action, _Unwind_Exception_Class, _Unwind_Exception