Index: docs/index.rst =================================================================== --- docs/index.rst +++ docs/index.rst @@ -50,7 +50,7 @@ Linux ARM Clang, GCC EHABI Bare Metal ARM Clang, GCC EHABI NetBSD x86_64 Clang, GCC DWARF CFI -Windows i386 Clang DWARF CFI +Windows i386, x86_64 Clang DWARF CFI Any i386, x86_64, ARM Clang SjLj ============ ==================== ============ ======================== Index: include/unwind.h =================================================================== --- include/unwind.h +++ include/unwind.h @@ -122,7 +122,7 @@ _Unwind_Exception *exc); uintptr_t private_1; // non-zero means forced unwind uintptr_t private_2; // holds sp that phase1 found for phase2 to use -#ifndef __LP64__ +#if !defined(__LP64__) && !defined(_WIN64) // The implementation of _Unwind_Exception uses an attribute mode on the // above fields which has the side effect of causing this whole struct to // round up to 32 bytes in size. To be more explicit, we add pad fields Index: src/AddressSpace.hpp =================================================================== --- src/AddressSpace.hpp +++ src/AddressSpace.hpp @@ -142,7 +142,7 @@ /// making local unwinds fast. class __attribute__((visibility("hidden"))) LocalAddressSpace { public: -#ifdef __LP64__ +#if defined(__LP64__) || defined(_WIN64) typedef uint64_t pint_t; typedef int64_t sint_t; #else @@ -194,7 +194,7 @@ }; inline uintptr_t LocalAddressSpace::getP(pint_t addr) { -#ifdef __LP64__ +#if defined(__LP64__) || defined(_WIN64) return get64(addr); #else return get32(addr); Index: src/UnwindLevel1.c =================================================================== --- src/UnwindLevel1.c +++ src/UnwindLevel1.c @@ -86,7 +86,7 @@ // this frame. if (frameInfo.handler != 0) { __personality_routine p = - (__personality_routine)(long)(frameInfo.handler); + (__personality_routine)(uintptr_t)(frameInfo.handler); _LIBUNWIND_TRACE_UNWINDING( "unwind_phase1(ex_ojb=%p): calling personality function %p", (void *)exception_object, (void *)(uintptr_t)p); @@ -181,7 +181,7 @@ // If there is a personality routine, tell it we are unwinding. if (frameInfo.handler != 0) { __personality_routine p = - (__personality_routine)(long)(frameInfo.handler); + (__personality_routine)(uintptr_t)(frameInfo.handler); _Unwind_Action action = _UA_CLEANUP_PHASE; if (sp == exception_object->private_2) { // Tell personality this was the frame it marked in phase 1. Index: src/UnwindRegistersRestore.S =================================================================== --- src/UnwindRegistersRestore.S +++ src/UnwindRegistersRestore.S @@ -65,6 +65,40 @@ # # void libunwind::Registers_x86_64::jumpto() # +#if defined(_WIN32) +# On entry, thread_state pointer is in rcx + + movq 56(%rcx), %rax # rax holds new stack pointer + subq $16, %rax + movq %rax, 56(%rcx) + movq 16(%rcx), %rdx # store new rcx on new stack + movq %rdx, 0(%rax) + movq 128(%rcx), %rdx # store new rip on new stack + movq %rdx, 8(%rax) + # restore all registers + movq 0(%rcx), %rax + movq 8(%rcx), %rbx + # restore rcx later + movq 24(%rcx), %rdx + movq 32(%rcx), %rdi + movq 40(%rcx), %rsi + movq 48(%rcx), %rbp + # restore rsp later + movq 64(%rcx), %r8 + movq 72(%rcx), %r9 + movq 80(%rcx), %r10 + movq 88(%rcx), %r11 + movq 96(%rcx), %r12 + movq 104(%rcx), %r13 + movq 112(%rcx), %r14 + movq 120(%rcx), %r15 + # skip rflags + # skip cs + # skip fs + # skip gs + movq 56(%rcx), %rsp # cut back rsp to new location + pop %rcx # rcx was saved here earlier +#else # On entry, thread_state pointer is in rdi movq 56(%rdi), %rax # rax holds new stack pointer @@ -97,6 +131,7 @@ # skip gs movq 56(%rdi), %rsp # cut back rsp to new location pop %rdi # rdi was saved here earlier +#endif ret # rip was saved here Index: src/UnwindRegistersSave.S =================================================================== --- src/UnwindRegistersSave.S +++ src/UnwindRegistersSave.S @@ -63,6 +63,27 @@ # thread_state pointer is in rdi # DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) +#if defined(_WIN32) + movq %rax, (%rcx) + movq %rbx, 8(%rcx) + movq %rcx, 16(%rcx) + movq %rdx, 24(%rcx) + movq %rdi, 32(%rcx) + movq %rsi, 40(%rcx) + movq %rbp, 48(%rcx) + movq %rsp, 56(%rcx) + addq $8, 56(%rcx) + movq %r8, 64(%rcx) + movq %r9, 72(%rcx) + movq %r10, 80(%rcx) + movq %r11, 88(%rcx) + movq %r12, 96(%rcx) + movq %r13,104(%rcx) + movq %r14,112(%rcx) + movq %r15,120(%rcx) + movq (%rsp),%rdx + movq %rdx,128(%rcx) # store return address as rip +#else movq %rax, (%rdi) movq %rbx, 8(%rdi) movq %rcx, 16(%rdi) @@ -82,6 +103,7 @@ movq %r15,120(%rdi) movq (%rsp),%rsi movq %rsi,128(%rdi) # store return address as rip +#endif # skip rflags # skip cs # skip fs