libunwind-devel
[Top][All Lists]
Advanced

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

[Libunwind-devel] [PATCH][x86_64] Implement a getcontext for x86_64


From: Arun Sharma
Subject: [Libunwind-devel] [PATCH][x86_64] Implement a getcontext for x86_64
Date: Tue, 10 Jun 2008 11:03:12 -0700
User-agent: Mutt/1.5.11

This patch eliminates one system call per unwind by not using the
getcontext in libc.

Also cleanup the namespace (check-name-space passes on x86_64 now).
Replace uses of offsets.h with ucontext_i.h.
Rename _x86_64_setcontext to _Ux86_64_setcontext.

TBD: Add CFI annotations for get/setcontext.

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

index a87b57e..e337351 100644
--- a/include/libunwind-x86_64.h
+++ b/include/libunwind-x86_64.h
@@ -97,22 +97,18 @@ unw_tdep_save_loc_t;
 /* On x86_64, we can directly use ucontext_t as the unwind context.  */
 typedef ucontext_t unw_tdep_context_t;
 
-/* XXX this is not ideal: an application should not be prevented from
-   using the "getcontext" name just because it's using libunwind.  We
-   can't just use __getcontext() either, because that isn't exported
-   by glibc...  */
-#define unw_tdep_getcontext(uc)                (getcontext (uc), 0)
-
-#include "libunwind-dynamic.h"
-
 typedef struct
   {
     /* no x86-64-specific auxiliary proc-info */
   }
 unw_tdep_proc_info_t;
 
+#include "libunwind-dynamic.h"
 #include "libunwind-common.h"
 
+#define unw_tdep_getcontext            UNW_ARCH_OBJ(getcontext)
+extern int unw_tdep_getcontext (unw_tdep_context_t *);
+
 #define unw_tdep_is_fpreg              UNW_ARCH_OBJ(is_fpreg)
 extern int unw_tdep_is_fpreg (int);
 
diff --git a/src/Makefile.am b/src/Makefile.am
index ae113f4..7739405 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -252,7 +252,7 @@ libunwind_la_SOURCES_x86_64_common = 
$(libunwind_la_SOURCES_common) \
        $(dwarf_SOURCES_common)                                         \
        elf64.c elf64.h                                                 \
        x86_64/init.h x86_64/unwind_i.h x86_64/ucontext_i.h             \
-       x86_64/is_fpreg.c x86_64/regname.c x86_64/offsets.h
+       x86_64/is_fpreg.c x86_64/regname.c
 
 # The list of files that go into libunwind:
 libunwind_la_SOURCES_x86_64 = $(libunwind_la_SOURCES_x86_64_common)        \
@@ -263,7 +263,7 @@ libunwind_la_SOURCES_x86_64 = 
$(libunwind_la_SOURCES_x86_64_common)     \
        x86_64/Lcreate_addr_space.c x86_64/Lget_save_loc.c x86_64/Lglobal.c \
        x86_64/Linit.c x86_64/Linit_local.c x86_64/Linit_remote.c           \
        x86_64/Lis_signal_frame.c x86_64/Lget_proc_info.c x86_64/Lregs.c    \
-       x86_64/Lresume.c x86_64/Lstep.c
+       x86_64/Lresume.c x86_64/Lstep.c x86_64/getcontext.S
 
 # The list of files that go into libunwind-x86_64:
 libunwind_x86_64_la_SOURCES_x86_64 = $(libunwind_la_SOURCES_x86_64_common)  \
diff --git a/src/x86_64/Gresume.c b/src/x86_64/Gresume.c
index 4edc4da..4ea3312 100644
--- a/src/x86_64/Gresume.c
+++ b/src/x86_64/Gresume.c
@@ -71,7 +71,7 @@ x86_64_local_resume (unw_addr_space_t as, unw_cursor_t 
*cursor, void *arg)
     {
       Debug (8, "resuming at ip=%llx via setcontext()\n",
             (unsigned long long) c->dwarf.ip);
-      _x86_64_setcontext (uc);
+      _Ux86_64_setcontext (uc);
     }
 #else
 # warning Implement me!
diff --git a/src/x86_64/offsets.h b/src/x86_64/offsets.h
deleted file mode 100644
index 56ead69..0000000
--- a/src/x86_64/offsets.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* This used to be a generated file. But then it breaks cross compilation.
- * So use the method used by other architectures.
- */
-#ifndef OFFSETS_H
-#define OFFSETS_H
-
-#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
-
-#endif /* OFFSETS_H */
diff --git a/src/x86_64/setcontext.S b/src/x86_64/setcontext.S
index 9eeb1b8..6b06a7b 100644
--- a/src/x86_64/setcontext.S
+++ b/src/x86_64/setcontext.S
@@ -23,38 +23,45 @@ 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.  */
 
-#include "offsets.h"
+#include "ucontext_i.h"
 
-       .global _x86_64_setcontext
 
-_x86_64_setcontext:
+/*  int _Ux86_64_setcontext (const ucontext_t *ucp)
+
+  Restores the machine context provided.
+  Unlike the libc implementation, doesn't clobber %rax
+  
+*/
+       .global _Ux86_64_setcontext
+
+_Ux86_64_setcontext:
 
         /* restore fp state */
-       mov    REG_OFFSET_FPREGS_PTR(%rdi),%r8
+       mov    UC_MCONTEXT_FPREGS_PTR(%rdi),%r8
        fldenv (%r8)
-       ldmxcsr FPREG_OFFSET_MXCR(%r8)
+       ldmxcsr FPREGS_OFFSET_MXCSR(%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
+       mov    UC_MCONTEXT_GREGS_R8(%rdi),%r8
+       mov    UC_MCONTEXT_GREGS_R9(%rdi),%r9
+       mov    UC_MCONTEXT_GREGS_RBX(%rdi),%rbx
+       mov    UC_MCONTEXT_GREGS_RBP(%rdi),%rbp
+       mov    UC_MCONTEXT_GREGS_R12(%rdi),%r12
+       mov    UC_MCONTEXT_GREGS_R13(%rdi),%r13
+       mov    UC_MCONTEXT_GREGS_R14(%rdi),%r14
+       mov    UC_MCONTEXT_GREGS_R15(%rdi),%r15
+       mov    UC_MCONTEXT_GREGS_RSI(%rdi),%rsi
+       mov    UC_MCONTEXT_GREGS_RDX(%rdi),%rdx
+       mov    UC_MCONTEXT_GREGS_RAX(%rdi),%rax
+       mov    UC_MCONTEXT_GREGS_RCX(%rdi),%rcx
+       mov    UC_MCONTEXT_GREGS_RSP(%rdi),%rsp
 
         /* push the return address on the stack */
-       mov    REG_OFFSET_RIP(%rdi),%rcx
+       mov    UC_MCONTEXT_GREGS_RIP(%rdi),%rcx
        push   %rcx
 
-       mov    REG_OFFSET_RCX(%rdi),%rcx
-       mov    REG_OFFSET_RDI(%rdi),%rdi
+       mov    UC_MCONTEXT_GREGS_RCX(%rdi),%rcx
+       mov    UC_MCONTEXT_GREGS_RDI(%rdi),%rdi
        retq
 
 #ifdef __linux__
diff --git a/src/x86_64/ucontext_i.h b/src/x86_64/ucontext_i.h
index dfd93bc..459c56a 100644
--- a/src/x86_64/ucontext_i.h
+++ b/src/x86_64/ucontext_i.h
@@ -39,3 +39,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
SOFTWARE.  */
 #define UC_MCONTEXT_GREGS_RCX  0x98
 #define UC_MCONTEXT_GREGS_RSP  0xa0
 #define UC_MCONTEXT_GREGS_RIP  0xa8
+#define UC_MCONTEXT_FPREGS_PTR  0x1a8
+#define UC_MCONTEXT_FPREGS_MEM 0xe0
+#define FPREGS_OFFSET_MXCSR    0x18
diff --git a/tests/check-namespace.sh.in b/tests/check-namespace.sh.in
index d6f5122..b7285b1 100644
--- a/tests/check-namespace.sh.in
+++ b/tests/check-namespace.sh.in
@@ -121,6 +121,7 @@ check_local_unw_abi () {
            match _U${plat}_get_elf_image
            match _U${plat}_is_fpreg
            match _UL${plat}_dwarf_search_unwind_table
+           match _U${plat}_setcontext
            ;;
        *)
            match _U${plat}_is_fpreg




reply via email to

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