[PATCH] D38819: [libunwind] Add support for dwarf unwinding on windows on x86_64

2017-10-27 Thread Martin Storsjö via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL316747: Add support for dwarf unwinding on windows on x86_64 
(authored by mstorsjo).

Changed prior to commit:
  https://reviews.llvm.org/D38819?vs=120380=120552#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D38819

Files:
  libunwind/trunk/docs/index.rst
  libunwind/trunk/include/__libunwind_config.h
  libunwind/trunk/include/libunwind.h
  libunwind/trunk/include/unwind.h
  libunwind/trunk/src/AddressSpace.hpp
  libunwind/trunk/src/Registers.hpp
  libunwind/trunk/src/UnwindLevel1.c
  libunwind/trunk/src/UnwindRegistersRestore.S
  libunwind/trunk/src/UnwindRegistersSave.S

Index: libunwind/trunk/docs/index.rst
===
--- libunwind/trunk/docs/index.rst
+++ libunwind/trunk/docs/index.rst
@@ -52,6 +52,7 @@
 Linuxi386, x86_64, ARM64  Clang, GCC   DWARF CFI
 Mac OS X i386, x86_64 Clang, GCC   DWARF CFI
 NetBSD   x86_64   Clang, GCC   DWARF CFI
+Windows  i386, x86_64 ClangDWARF CFI
    
 
 The following minimum compiler versions are strongly recommended.
Index: libunwind/trunk/src/UnwindLevel1.c
===
--- libunwind/trunk/src/UnwindLevel1.c
+++ libunwind/trunk/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: libunwind/trunk/src/Registers.hpp
===
--- libunwind/trunk/src/Registers.hpp
+++ libunwind/trunk/src/Registers.hpp
@@ -245,7 +245,7 @@
   boolvalidFloatRegister(int) const { return false; }
   double  getFloatRegister(int num) const;
   voidsetFloatRegister(int num, double value);
-  boolvalidVectorRegister(int) const { return false; }
+  boolvalidVectorRegister(int) const;
   v128getVectorRegister(int num) const;
   voidsetVectorRegister(int num, v128 value);
   const char *getRegisterName(int num);
@@ -292,8 +292,14 @@
 uint64_t __cs;
 uint64_t __fs;
 uint64_t __gs;
+#if defined(_WIN64)
+uint64_t __padding; // 16-byte align
+#endif
   };
   GPRs _registers;
+#if defined(_WIN64)
+  v128 _xmm[16];
+#endif
 };
 
 inline Registers_x86_64::Registers_x86_64(const void *registers) {
@@ -458,6 +464,38 @@
 return "r14";
   case UNW_X86_64_R15:
 return "r15";
+  case UNW_X86_64_XMM0:
+return "xmm0";
+  case UNW_X86_64_XMM1:
+return "xmm1";
+  case UNW_X86_64_XMM2:
+return "xmm2";
+  case UNW_X86_64_XMM3:
+return "xmm3";
+  case UNW_X86_64_XMM4:
+return "xmm4";
+  case UNW_X86_64_XMM5:
+return "xmm5";
+  case UNW_X86_64_XMM6:
+return "xmm6";
+  case UNW_X86_64_XMM7:
+return "xmm7";
+  case UNW_X86_64_XMM8:
+return "xmm8";
+  case UNW_X86_64_XMM9:
+return "xmm9";
+  case UNW_X86_64_XMM10:
+return "xmm10";
+  case UNW_X86_64_XMM11:
+return "xmm11";
+  case UNW_X86_64_XMM12:
+return "xmm12";
+  case UNW_X86_64_XMM13:
+return "xmm13";
+  case UNW_X86_64_XMM14:
+return "xmm14";
+  case UNW_X86_64_XMM15:
+return "xmm15";
   default:
 return "unknown register";
   }
@@ -471,12 +509,34 @@
   _LIBUNWIND_ABORT("no x86_64 float registers");
 }
 
-inline v128 Registers_x86_64::getVectorRegister(int) const {
+inline bool Registers_x86_64::validVectorRegister(int regNum) const {
+#if defined(_WIN64)
+  if (regNum < UNW_X86_64_XMM0)
+return false;
+  if (regNum > UNW_X86_64_XMM15)
+return false;
+  return true;
+#else
+  return false;
+#endif
+}
+
+inline v128 Registers_x86_64::getVectorRegister(int regNum) const {
+#if defined(_WIN64)
+  assert(validVectorRegister(regNum));
+  return _xmm[regNum - UNW_X86_64_XMM0];
+#else
   _LIBUNWIND_ABORT("no x86_64 vector registers");
+#endif
 }
 
-inline void Registers_x86_64::setVectorRegister(int, v128) {
+inline void Registers_x86_64::setVectorRegister(int regNum, v128 value) {
+#if defined(_WIN64)
+  assert(validVectorRegister(regNum));
+  _xmm[regNum - UNW_X86_64_XMM0] = value;
+#else
   _LIBUNWIND_ABORT("no x86_64 vector 

[PATCH] D38819: [libunwind] Add support for dwarf unwinding on windows on x86_64

2017-10-26 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.

lgtm


https://reviews.llvm.org/D38819



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


[PATCH] D38819: [libunwind] Add support for dwarf unwinding on windows on x86_64

2017-10-26 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo updated this revision to Diff 120380.
mstorsjo added a comment.

Simplified the assembly by sharing much more code between the unix and win64 
paths, added a padding element to ensure more stable struct packing.


https://reviews.llvm.org/D38819

Files:
  docs/index.rst
  include/__libunwind_config.h
  include/libunwind.h
  include/unwind.h
  src/AddressSpace.hpp
  src/Registers.hpp
  src/UnwindLevel1.c
  src/UnwindRegistersRestore.S
  src/UnwindRegistersSave.S

Index: src/UnwindRegistersSave.S
===
--- src/UnwindRegistersSave.S
+++ src/UnwindRegistersSave.S
@@ -63,29 +63,56 @@
 #  thread_state pointer is in rdi
 #
 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
-  movq  %rax,   (%rdi)
-  movq  %rbx,  8(%rdi)
-  movq  %rcx, 16(%rdi)
-  movq  %rdx, 24(%rdi)
-  movq  %rdi, 32(%rdi)
-  movq  %rsi, 40(%rdi)
-  movq  %rbp, 48(%rdi)
-  movq  %rsp, 56(%rdi)
-  addq  $8,   56(%rdi)
-  movq  %r8,  64(%rdi)
-  movq  %r9,  72(%rdi)
-  movq  %r10, 80(%rdi)
-  movq  %r11, 88(%rdi)
-  movq  %r12, 96(%rdi)
-  movq  %r13,104(%rdi)
-  movq  %r14,112(%rdi)
-  movq  %r15,120(%rdi)
-  movq  (%rsp),%rsi
-  movq  %rsi,128(%rdi) # store return address as rip
+#if defined(_WIN64)
+#define PTR %rcx
+#define TMP %rdx
+#else
+#define PTR %rdi
+#define TMP %rsi
+#endif
+
+  movq  %rax,   (PTR)
+  movq  %rbx,  8(PTR)
+  movq  %rcx, 16(PTR)
+  movq  %rdx, 24(PTR)
+  movq  %rdi, 32(PTR)
+  movq  %rsi, 40(PTR)
+  movq  %rbp, 48(PTR)
+  movq  %rsp, 56(PTR)
+  addq  $8,   56(PTR)
+  movq  %r8,  64(PTR)
+  movq  %r9,  72(PTR)
+  movq  %r10, 80(PTR)
+  movq  %r11, 88(PTR)
+  movq  %r12, 96(PTR)
+  movq  %r13,104(PTR)
+  movq  %r14,112(PTR)
+  movq  %r15,120(PTR)
+  movq  (%rsp),TMP
+  movq  TMP,128(PTR) # store return address as rip
   # skip rflags
   # skip cs
   # skip fs
   # skip gs
+
+#if defined(_WIN64)
+  movdqu %xmm0,176(PTR)
+  movdqu %xmm1,192(PTR)
+  movdqu %xmm2,208(PTR)
+  movdqu %xmm3,224(PTR)
+  movdqu %xmm4,240(PTR)
+  movdqu %xmm5,256(PTR)
+  movdqu %xmm6,272(PTR)
+  movdqu %xmm7,288(PTR)
+  movdqu %xmm8,304(PTR)
+  movdqu %xmm9,320(PTR)
+  movdqu %xmm10,336(PTR)
+  movdqu %xmm11,352(PTR)
+  movdqu %xmm12,368(PTR)
+  movdqu %xmm13,384(PTR)
+  movdqu %xmm14,400(PTR)
+  movdqu %xmm15,416(PTR)
+#endif
   xorl  %eax, %eax# return UNW_ESUCCESS
   ret
 
Index: src/UnwindRegistersRestore.S
===
--- src/UnwindRegistersRestore.S
+++ src/UnwindRegistersRestore.S
@@ -65,7 +65,16 @@
 #
 # void libunwind::Registers_x86_64::jumpto()
 #
+#if defined(_WIN64)
+# On entry, thread_state pointer is in rcx; move it into rdi
+# to share restore code below. Since this routine restores and
+# overwrites all registers, we can use the same registers for
+# pointers and temporaries as on unix even though win64 normally
+# mustn't clobber some of them.
+  movq  %rcx, %rdi
+#else
 # On entry, thread_state pointer is in rdi
+#endif
 
   movq  56(%rdi), %rax # rax holds new stack pointer
   subq  $16, %rax
@@ -95,6 +104,25 @@
   # skip cs
   # skip fs
   # skip gs
+
+#if defined(_WIN64)
+  movdqu 176(%rdi),%xmm0
+  movdqu 192(%rdi),%xmm1
+  movdqu 208(%rdi),%xmm2
+  movdqu 224(%rdi),%xmm3
+  movdqu 240(%rdi),%xmm4
+  movdqu 256(%rdi),%xmm5
+  movdqu 272(%rdi),%xmm6
+  movdqu 288(%rdi),%xmm7
+  movdqu 304(%rdi),%xmm8
+  movdqu 320(%rdi),%xmm9
+  movdqu 336(%rdi),%xmm10
+  movdqu 352(%rdi),%xmm11
+  movdqu 368(%rdi),%xmm12
+  movdqu 384(%rdi),%xmm13
+  movdqu 400(%rdi),%xmm14
+  movdqu 416(%rdi),%xmm15
+#endif
   movq  56(%rdi), %rsp  # cut back rsp to new location
   pop%rdi  # rdi was saved here earlier
   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/Registers.hpp
===
--- src/Registers.hpp
+++ src/Registers.hpp
@@ -245,12 +245,16 @@
   boolvalidFloatRegister(int) const { return false; }
   double  getFloatRegister(int num) const;
   voidsetFloatRegister(int 

[PATCH] D38819: [libunwind] Add support for dwarf unwinding on windows on x86_64

2017-10-25 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo added inline comments.



Comment at: src/UnwindRegistersRestore.S:72
+  movq  56(%rcx), %rax # rax holds new stack pointer
+  subq  $16, %rax
+  movq  %rax, 56(%rcx)

mstorsjo wrote:
> compnerd wrote:
> > Hmm, why is this `$16`?  The `$rsp` was adjusted by `$8` in the `setjmp`.
> This is the exact same thing as is done right now for x86_64 on unixy systems 
> already, just with different registers.
> 
> The adjustment by 16 bytes is because we store `rcx` and `rip` on the stack 
> here to restore them slightly differently than the others. See the `store new 
> rcx/rip on new stack`, `restore rcx later` and `rcx was saved here earlier` 
> and `rip was saved here` comments below.
Instead of duplicating the asm for the win64 and unix calling convention, I can 
also pretty easily template it using the cpp, using a define for whatever 
register holds the context pointer from the first function argument. Would that 
be better, or is it clearer just to have it typed out in both forms literally?


https://reviews.llvm.org/D38819



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


[PATCH] D38819: [libunwind] Add support for dwarf unwinding on windows on x86_64

2017-10-25 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo updated this revision to Diff 120215.
mstorsjo edited the summary of this revision.
mstorsjo added a comment.

Updated to take care of saving/restoring XMM registers as well.


https://reviews.llvm.org/D38819

Files:
  docs/index.rst
  include/__libunwind_config.h
  include/libunwind.h
  include/unwind.h
  src/AddressSpace.hpp
  src/Registers.hpp
  src/UnwindLevel1.c
  src/UnwindRegistersRestore.S
  src/UnwindRegistersSave.S

Index: src/UnwindRegistersSave.S
===
--- src/UnwindRegistersSave.S
+++ src/UnwindRegistersSave.S
@@ -63,6 +63,43 @@
 #  thread_state pointer is in rdi
 #
 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
+#if defined(_WIN64)
+  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
+  movdqu %xmm0,168(%rcx)
+  movdqu %xmm1,184(%rcx)
+  movdqu %xmm2,200(%rcx)
+  movdqu %xmm3,216(%rcx)
+  movdqu %xmm4,232(%rcx)
+  movdqu %xmm5,248(%rcx)
+  movdqu %xmm6,264(%rcx)
+  movdqu %xmm7,280(%rcx)
+  movdqu %xmm8,296(%rcx)
+  movdqu %xmm9,312(%rcx)
+  movdqu %xmm10,328(%rcx)
+  movdqu %xmm11,344(%rcx)
+  movdqu %xmm12,360(%rcx)
+  movdqu %xmm13,376(%rcx)
+  movdqu %xmm14,392(%rcx)
+  movdqu %xmm15,408(%rcx)
+#else
   movq  %rax,   (%rdi)
   movq  %rbx,  8(%rdi)
   movq  %rcx, 16(%rdi)
@@ -82,6 +119,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,56 @@
 #
 # void libunwind::Registers_x86_64::jumpto()
 #
+#if defined(_WIN64)
+# 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
+  movq0(%rcx), %rax
+  movq8(%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
+  movdqu 168(%rcx),%xmm0
+  movdqu 184(%rcx),%xmm1
+  movdqu 200(%rcx),%xmm2
+  movdqu 216(%rcx),%xmm3
+  movdqu 232(%rcx),%xmm4
+  movdqu 248(%rcx),%xmm5
+  movdqu 264(%rcx),%xmm6
+  movdqu 280(%rcx),%xmm7
+  movdqu 296(%rcx),%xmm8
+  movdqu 312(%rcx),%xmm9
+  movdqu 328(%rcx),%xmm10
+  movdqu 344(%rcx),%xmm11
+  movdqu 360(%rcx),%xmm12
+  movdqu 376(%rcx),%xmm13
+  movdqu 392(%rcx),%xmm14
+  movdqu 408(%rcx),%xmm15
+  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 +147,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/Registers.hpp
===
--- src/Registers.hpp
+++ src/Registers.hpp
@@ -245,12 +245,12 @@
   boolvalidFloatRegister(int) const { return false; }
   double  getFloatRegister(int num) const;
   

[PATCH] D38819: [libunwind] Add support for dwarf unwinding on windows on x86_64

2017-10-23 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo added inline comments.



Comment at: src/UnwindRegistersRestore.S:98
+  # skip fs
+  # skip gs
+  movq  56(%rcx), %rsp  # cut back rsp to new location

rnk wrote:
> mstorsjo wrote:
> > mstorsjo wrote:
> > > compnerd wrote:
> > > > Doesn't Win64 ABI require some of the MMX registers be saved/restored 
> > > > too?
> > > Right, yes, xmm6-xmm15 should be backed up and restored. I'll try to 
> > > amend this with such a change.
> > Actually, such a change doesn't necessarily make much sense on its own.
> > 
> > As long as the dwarf encoding itself doesn't describe how to restore those 
> > registers (and on unix platforms you don't need to, so it probably isn't 
> > even specified), you'd just end up backing up the xmm registers on entry 
> > when throwing the exception, and restoring the exactly same ones again - it 
> > only guards against changes within libcxxabi/libunwind and the unwinding 
> > machinery itself, not against changes further down in the call stack 
> > between the thrower and catcher of the exception.
> > 
> > So with that, I guess this patch is futile unless planning to extend the 
> > x86_64 dwarf handling in llvm to include those registers as well - and 
> > that's a little out of scope of what I intended to do here...
> If we have XMM values in the register context, we might as well reload them 
> here. I assume libunwind will switch away from DWARF and over to UNWIND_INFO 
> opcodes in the near future, and that will give us an accurate register 
> context.
Yeah, although to do anything useful with the XMM registers, the llvm backend 
would have to output dwarf opcodes for callee saved xmm registers, which it 
currently doesn't. Otherwise it'll just reload them back to the same values as 
they already are. I've managed to hack LLVM to do that (without fully 
understanding what I'm doing though), and I'll see if I manage to update 
libunwind to use that as well. 


https://reviews.llvm.org/D38819



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


[PATCH] D38819: [libunwind] Add support for dwarf unwinding on windows on x86_64

2017-10-23 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added inline comments.



Comment at: src/UnwindRegistersRestore.S:98
+  # skip fs
+  # skip gs
+  movq  56(%rcx), %rsp  # cut back rsp to new location

mstorsjo wrote:
> mstorsjo wrote:
> > compnerd wrote:
> > > Doesn't Win64 ABI require some of the MMX registers be saved/restored too?
> > Right, yes, xmm6-xmm15 should be backed up and restored. I'll try to amend 
> > this with such a change.
> Actually, such a change doesn't necessarily make much sense on its own.
> 
> As long as the dwarf encoding itself doesn't describe how to restore those 
> registers (and on unix platforms you don't need to, so it probably isn't even 
> specified), you'd just end up backing up the xmm registers on entry when 
> throwing the exception, and restoring the exactly same ones again - it only 
> guards against changes within libcxxabi/libunwind and the unwinding machinery 
> itself, not against changes further down in the call stack between the 
> thrower and catcher of the exception.
> 
> So with that, I guess this patch is futile unless planning to extend the 
> x86_64 dwarf handling in llvm to include those registers as well - and that's 
> a little out of scope of what I intended to do here...
If we have XMM values in the register context, we might as well reload them 
here. I assume libunwind will switch away from DWARF and over to UNWIND_INFO 
opcodes in the near future, and that will give us an accurate register context.


https://reviews.llvm.org/D38819



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


[PATCH] D38819: [libunwind] Add support for dwarf unwinding on windows on x86_64

2017-10-23 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo added inline comments.



Comment at: src/UnwindRegistersRestore.S:98
+  # skip fs
+  # skip gs
+  movq  56(%rcx), %rsp  # cut back rsp to new location

mstorsjo wrote:
> compnerd wrote:
> > Doesn't Win64 ABI require some of the MMX registers be saved/restored too?
> Right, yes, xmm6-xmm15 should be backed up and restored. I'll try to amend 
> this with such a change.
Actually, such a change doesn't necessarily make much sense on its own.

As long as the dwarf encoding itself doesn't describe how to restore those 
registers (and on unix platforms you don't need to, so it probably isn't even 
specified), you'd just end up backing up the xmm registers on entry when 
throwing the exception, and restoring the exactly same ones again - it only 
guards against changes within libcxxabi/libunwind and the unwinding machinery 
itself, not against changes further down in the call stack between the thrower 
and catcher of the exception.

So with that, I guess this patch is futile unless planning to extend the x86_64 
dwarf handling in llvm to include those registers as well - and that's a little 
out of scope of what I intended to do here...


https://reviews.llvm.org/D38819



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


[PATCH] D38819: [libunwind] Add support for dwarf unwinding on windows on x86_64

2017-10-22 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo added inline comments.



Comment at: src/UnwindRegistersRestore.S:98
+  # skip fs
+  # skip gs
+  movq  56(%rcx), %rsp  # cut back rsp to new location

compnerd wrote:
> Doesn't Win64 ABI require some of the MMX registers be saved/restored too?
Right, yes, xmm6-xmm15 should be backed up and restored. I'll try to amend this 
with such a change.


https://reviews.llvm.org/D38819



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


[PATCH] D38819: [libunwind] Add support for dwarf unwinding on windows on x86_64

2017-10-22 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd added inline comments.



Comment at: src/UnwindRegistersRestore.S:98
+  # skip fs
+  # skip gs
+  movq  56(%rcx), %rsp  # cut back rsp to new location

Doesn't Win64 ABI require some of the MMX registers be saved/restored too?


https://reviews.llvm.org/D38819



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


[PATCH] D38819: [libunwind] Add support for dwarf unwinding on windows on x86_64

2017-10-20 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo added a comment.

Ping


https://reviews.llvm.org/D38819



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


[PATCH] D38819: [libunwind] Add support for dwarf unwinding on windows on x86_64

2017-10-15 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo added inline comments.



Comment at: docs/index.rst:55
 NetBSD   x86_64   Clang, GCC   DWARF CFI
-Windows  i386 ClangDWARF CFI
+Windows  i386, x86_64 ClangDWARF CFI
    

martell wrote:
> Based on your comments above I assume this supports GCC also ?
> If so, replace
> `Windows  i386, x86_64 ClangDWARF CFI`
> with
> `Windows  i386, x86_64 Clang, GCC   DWARF CFI`
> 
> This is exciting stuff Martin :)
I'm not sure if gcc supports dwarf exceptions on x86_64 or how much hacking is 
needed to enable it; the comment about gcc for `__SIZEOF_POINTER__` was because 
it was in generic code that could be used by gcc in one of the existing cases 
where gcc actually is supported.


https://reviews.llvm.org/D38819



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


[PATCH] D38819: [libunwind] Add support for dwarf unwinding on windows on x86_64

2017-10-15 Thread Martell Malone via Phabricator via cfe-commits
martell added inline comments.



Comment at: docs/index.rst:55
 NetBSD   x86_64   Clang, GCC   DWARF CFI
-Windows  i386 ClangDWARF CFI
+Windows  i386, x86_64 ClangDWARF CFI
    

Based on your comments above I assume this supports GCC also ?
If so, replace
`Windows  i386, x86_64 ClangDWARF CFI`
with
`Windows  i386, x86_64 Clang, GCC   DWARF CFI`

This is exciting stuff Martin :)


https://reviews.llvm.org/D38819



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


[PATCH] D38819: [libunwind] Add support for dwarf unwinding on windows on x86_64

2017-10-15 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo updated this revision to Diff 119068.
mstorsjo added a comment.

Use `__SIZEOF_POINTER__` instead of checking `__LP64__` together with `_WIN64`. 
Changed `_WIN32` into `_WIN64` within the assembly sources for 
consistency/clarity. Removed one type definition ifdef by just using 
`(u)intptr_t` instead.


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(_WIN64)
+  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(_WIN64)
+# 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
+  movq0(%rcx), %rax
+  movq8(%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,13 +142,8 @@
 /// making local unwinds fast.
 class __attribute__((visibility("hidden"))) LocalAddressSpace {
 public:
-#ifdef __LP64__
-  typedef uint64_t pint_t;
-  typedef int64_t  sint_t;
-#else
-  typedef uint32_t pint_t;
-  typedef int32_t  sint_t;
-#endif
+  typedef uintptr_t pint_t;
+  typedef intptr_t  sint_t;
   uint8_t get8(pint_t addr) {
 uint8_t val;
 memcpy(, (void *)addr, sizeof(val));
@@ -194,7 +189,7 @@
 };
 
 inline uintptr_t LocalAddressSpace::getP(pint_t addr) {
-#ifdef __LP64__
+#if __SIZEOF_POINTER__ == 8
   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 

[PATCH] D38819: [libunwind] Add support for dwarf unwinding on windows on x86_64

2017-10-15 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo added inline comments.



Comment at: include/unwind.h:125
   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

compnerd wrote:
> I think I would prefer that we do this generically as:
> 
> #if __POINTER_WIDTH__ == 32
It seems like GCC doesn't set `__POINTER_WIDTH__`, but both GCC and clang set 
`__SIZEOF_POINTER__`, so I can use that.



Comment at: src/AddressSpace.hpp:145
 public:
-#ifdef __LP64__
+#if defined(__LP64__) || defined(_WIN64)
   typedef uint64_t pint_t;

compnerd wrote:
> I think I prefer the generic:
> 
> #if __POINTER_WIDTH__ == 64
This one probably could be simplified even further by just using `intptr_t` and 
`uintptr_t`, right?



Comment at: src/UnwindRegistersRestore.S:68
 #
+#if defined(_WIN32)
+# On entry, thread_state pointer is in rcx

compnerd wrote:
> This is confusing.  Why is this `_WIN32`?  Shouldn't this be `_WIN64`?
I guess I could use that as well. I just used `_WIN32` out of habit as generic 
identifier for windows-in-whatever-form; both `_WIN32` and `_WIN64` are 
defined, and we're within an `#ifdef __x86_64__` anyway. I can change it into 
`_WIN64` for clarity.



Comment at: src/UnwindRegistersRestore.S:72
+  movq  56(%rcx), %rax # rax holds new stack pointer
+  subq  $16, %rax
+  movq  %rax, 56(%rcx)

compnerd wrote:
> Hmm, why is this `$16`?  The `$rsp` was adjusted by `$8` in the `setjmp`.
This is the exact same thing as is done right now for x86_64 on unixy systems 
already, just with different registers.

The adjustment by 16 bytes is because we store `rcx` and `rip` on the stack 
here to restore them slightly differently than the others. See the `store new 
rcx/rip on new stack`, `restore rcx later` and `rcx was saved here earlier` and 
`rip was saved here` comments below.



Comment at: src/UnwindRegistersSave.S:66
 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
+#if defined(_WIN32)
+  movq  %rax,   (%rcx)

compnerd wrote:
> Shouldn't this be `_WIN64`?
Same as the otherone; we're within `#ifdef __x86_64__`, but I can change it 
into `_WIN64` for clarity.


https://reviews.llvm.org/D38819



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


[PATCH] D38819: [libunwind] Add support for dwarf unwinding on windows on x86_64

2017-10-14 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd added inline comments.



Comment at: include/unwind.h:125
   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

I think I would prefer that we do this generically as:

#if __POINTER_WIDTH__ == 32



Comment at: src/AddressSpace.hpp:145
 public:
-#ifdef __LP64__
+#if defined(__LP64__) || defined(_WIN64)
   typedef uint64_t pint_t;

I think I prefer the generic:

#if __POINTER_WIDTH__ == 64



Comment at: src/AddressSpace.hpp:197
 inline uintptr_t LocalAddressSpace::getP(pint_t addr) {
-#ifdef __LP64__
+#if defined(__LP64__) || defined(_WIN64)
   return get64(addr);

Same.



Comment at: src/UnwindRegistersRestore.S:68
 #
+#if defined(_WIN32)
+# On entry, thread_state pointer is in rcx

This is confusing.  Why is this `_WIN32`?  Shouldn't this be `_WIN64`?



Comment at: src/UnwindRegistersRestore.S:72
+  movq  56(%rcx), %rax # rax holds new stack pointer
+  subq  $16, %rax
+  movq  %rax, 56(%rcx)

Hmm, why is this `$16`?  The `$rsp` was adjusted by `$8` in the `setjmp`.



Comment at: src/UnwindRegistersSave.S:66
 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
+#if defined(_WIN32)
+  movq  %rax,   (%rcx)

Shouldn't this be `_WIN64`?


https://reviews.llvm.org/D38819



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


[PATCH] D38819: [libunwind] Add support for dwarf unwinding on windows on x86_64

2017-10-11 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo added a comment.

As further explanation/justification - libcxxabi and libunwind don't support 
SEH exceptions yet.


https://reviews.llvm.org/D38819



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


[PATCH] D38819: [libunwind] Add support for dwarf unwinding on windows on x86_64

2017-10-11 Thread Martin Storsjö via Phabricator via cfe-commits
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
+  movq0(%rcx), %rax
+  movq8(%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