libunwind-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Libunwind-devel] [PATCH] x86_64: Make libunwind pass C++ exceptions cor


From: Arun Sharma
Subject: [Libunwind-devel] [PATCH] x86_64: Make libunwind pass C++ exceptions correctly
Date: Thu, 5 Apr 2007 17:00:12 -0700
User-agent: Mutt/1.5.11

Make libunwind pass C++ exceptions correctly

When libunwind is linked with a C++ program that throws exceptions, the 
exception that's thrown is passed in %rax. However, libc's setcontext
clears %rax, causing problems.

This patch implements a setcontext that doesn't clobber rax.
TBD: Add dwarf CFI annotations

Signed-off-by: Arun Sharma <address@hidden>

--- a/src/x86_64/Gresume.c
+++ b/src/x86_64/Gresume.c
@@ -71,7 +71,7 @@ #if defined(__linux)
     {
       Debug (8, "resuming at ip=%llx via setcontext()\n",
             (unsigned long long) c->dwarf.ip);
-      setcontext (uc);
+      _x86_64_setcontext (uc);
     }
 #else
 # warning Implement me!
--- a/src/x86_64/setcontext.S
+++ b/src/x86_64/setcontext.S
@@ -1,4 +1,79 @@
-       .global _UI_setcontext
+/* libunwind - a platform-independent unwind library
+   Copyright (C) 2007 Google, Inc
+       Contributed by Arun Sharma <address@hidden>
 
-_UI_setcontext:
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#define REG_OFFSET_RAX  144
+#define REG_OFFSET_RBX  128
+#define REG_OFFSET_RCX  152
+#define REG_OFFSET_RDX  136
+#define REG_OFFSET_RDI  104
+#define REG_OFFSET_RSI  112
+#define REG_OFFSET_RSP  160
+#define REG_OFFSET_RBP  120
+#define REG_OFFSET_R8   40
+#define REG_OFFSET_R9   48
+#define REG_OFFSET_R10  56
+#define REG_OFFSET_R11  64
+#define REG_OFFSET_R12  72
+#define REG_OFFSET_R13  80
+#define REG_OFFSET_R14  88
+#define REG_OFFSET_R15  96
+#define REG_OFFSET_R15  96
+#define REG_OFFSET_R15  96
+#define REG_OFFSET_RIP  168
+#define REG_OFFSET_FPREGS_PTR   224
+#define FPREG_OFFSET_MXCR       24
+
+       .global _x86_64_setcontext
+
+_x86_64_setcontext:
+
+        /* restore fp state */
+       mov    REG_OFFSET_FPREGS_PTR(%rdi),%r8
+       fldenv (%r8)
+       ldmxcsr FPREG_OFFSET_MXCR(%r8)
+
+       /* restore the rest of the state */
+       mov    REG_OFFSET_R8(%rdi),%r8
+       mov    REG_OFFSET_R9(%rdi),%r9
+       mov    REG_OFFSET_RBX(%rdi),%rbx
+       mov    REG_OFFSET_RBP(%rdi),%rbp
+       mov    REG_OFFSET_R12(%rdi),%r12
+       mov    REG_OFFSET_R13(%rdi),%r13
+       mov    REG_OFFSET_R14(%rdi),%r14
+       mov    REG_OFFSET_R15(%rdi),%r15
+       mov    REG_OFFSET_RSI(%rdi),%rsi
+       mov    REG_OFFSET_RDX(%rdi),%rdx
+       mov    REG_OFFSET_RAX(%rdi),%rax
+       mov    REG_OFFSET_RCX(%rdi),%rcx
+       mov    REG_OFFSET_RSP(%rdi),%rsp
+
+        /* push the return address on the stack */
+       mov    REG_OFFSET_RIP(%rdi),%rcx
+       push   %rcx
+
+       mov    REG_OFFSET_RCX(%rdi),%rcx
+       mov    REG_OFFSET_RDI(%rdi),%rdi
        retq
+
--- /dev/null   2006-05-22 07:25:23.000000000 -0700
+++ libunwind/src/x86_64/gen-offsets.c  2007-04-05 16:47:55.000000000 -0700
@@ -0,0 +1,73 @@
+#include <ucontext.h>
+#include <stdio.h>
+#include <stddef.h>
+
+#define REG_OFFSET(reg) (offsetof(struct ucontext, 
uc_mcontext.gregs[REG_##reg]))
+
+# define REG_R8                0
+# define REG_R9                1
+# define REG_R10       2
+# define REG_R11       3
+# define REG_R12       4
+# define REG_R13       5
+# define REG_R14       6
+# define REG_R15       7
+# define REG_RDI       8
+# define REG_RSI       9
+# define REG_RBP       10
+# define REG_RBX       11
+# define REG_RDX       12
+# define REG_RAX       13
+# define REG_RCX       14
+# define REG_RSP       15
+# define REG_RIP       16
+
+char *regs[] = { "RAX",
+       "RBX",
+       "RCX",
+       "RDX",
+       "RDI",
+       "RSI",
+       "RSP",
+       "RBP",
+       "R8",
+       "R9",
+       "R10",
+       "R11",
+       "R12",
+       "R13",
+       "R14",
+       "R15",
+       "RIP",
+       };
+
+main()
+{
+       printf("#define REG_OFFSET_%s\t%d\n" , regs[0], REG_OFFSET(RAX));
+       printf("#define REG_OFFSET_%s\t%d\n" , regs[1], REG_OFFSET(RBX));
+       printf("#define REG_OFFSET_%s\t%d\n" , regs[2], REG_OFFSET(RCX));
+       printf("#define REG_OFFSET_%s\t%d\n" , regs[3], REG_OFFSET(RDX));
+
+       printf("#define REG_OFFSET_%s\t%d\n" , regs[4], REG_OFFSET(RDI));
+       printf("#define REG_OFFSET_%s\t%d\n" , regs[5], REG_OFFSET(RSI));
+       printf("#define REG_OFFSET_%s\t%d\n" , regs[6], REG_OFFSET(RSP));
+       printf("#define REG_OFFSET_%s\t%d\n" , regs[7], REG_OFFSET(RBP));
+
+       printf("#define REG_OFFSET_%s\t%d\n" , regs[8], REG_OFFSET(R8));
+       printf("#define REG_OFFSET_%s\t%d\n" , regs[9], REG_OFFSET(R9));
+       printf("#define REG_OFFSET_%s\t%d\n" , regs[10], REG_OFFSET(R10));
+       printf("#define REG_OFFSET_%s\t%d\n" , regs[11], REG_OFFSET(R11));
+
+       printf("#define REG_OFFSET_%s\t%d\n" , regs[12], REG_OFFSET(R12));
+       printf("#define REG_OFFSET_%s\t%d\n" , regs[13], REG_OFFSET(R13));
+       printf("#define REG_OFFSET_%s\t%d\n" , regs[14], REG_OFFSET(R14));
+       printf("#define REG_OFFSET_%s\t%d\n" , regs[15], REG_OFFSET(R15));
+       printf("#define REG_OFFSET_%s\t%d\n" , regs[15], REG_OFFSET(R15));
+       printf("#define REG_OFFSET_%s\t%d\n" , regs[15], REG_OFFSET(R15));
+       printf("#define REG_OFFSET_%s\t%d\n" , regs[16], REG_OFFSET(RIP));
+
+       printf("#define REG_OFFSET_FPREGS_PTR\t%d\n" , offsetof(struct 
ucontext, uc_mcontext.fpregs));
+       printf("#define FPREG_OFFSET_MXCR\t%d\n" , offsetof(struct 
_libc_fpstate, mxcsr));
+}
+
+




reply via email to

[Prev in Thread] Current Thread [Next in Thread]