mstorsjo created this revision. Herald added a subscriber: aprantl. Clang doesn't currently support building for windows/x86_64 with dwarf by setting command line parameters, but if manually modified to use dwarf, we can make libunwind work in this configuration as well.
Even if support for this is deemed pointless, I guess one could omit the assembly changes, but the fixes for the generic code probably are worthwhile at least. https://reviews.llvm.org/D38819 Files: docs/index.rst include/unwind.h src/AddressSpace.hpp src/UnwindLevel1.c src/UnwindRegistersRestore.S src/UnwindRegistersSave.S
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 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/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/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: 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: 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 ============ ==================== ============ ========================
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits