[Top][All Lists]
[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
- [Libunwind-devel] [PATCH][x86_64] Implement a getcontext for x86_64,
Arun Sharma <=