[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Libunwind-devel] Re: [PATCH][x86_64] Implement a getcontext for x86
From: |
David Mosberger-Tang |
Subject: |
Re: [Libunwind-devel] Re: [PATCH][x86_64] Implement a getcontext for x86_64 |
Date: |
Mon, 16 Jun 2008 15:08:12 -0600 |
Applied, thanks!
--david
On 6/10/08, Arun Sharma <address@hidden> wrote:
> [ The earlier patch was missing getcontext.S ]
>
>
> 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
>
> --- a/src/x86_64/getcontext.S
> +++ b/src/x86_64/getcontext.S
> @@ -0,0 +1,77 @@
> +/* libunwind - a platform-independent unwind library
> + Copyright (C) 2008 Google, Inc
> + Contributed by Paul Pluzhnikov <address@hidden>
> +
> +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. */
> +
>
> +#include "ucontext_i.h"
> +
> +/* int _Ux86_64_getcontext (ucontext_t *ucp)
> +
> + Saves the machine context in UCP necessary for libunwind.
> + Unlike the libc implementation, we don't save the signal mask
> + and hence avoid the cost of a system call per unwind.
> +
> +*/
> +
> + .global _Ux86_64_getcontext
> + .type _Ux86_64_getcontext, @function
> +_Ux86_64_getcontext:
> +
> + /* Callee saved: RBX, RBP, R12-R15 */
> + movq %r12, UC_MCONTEXT_GREGS_R12(%rdi)
> + movq %r13, UC_MCONTEXT_GREGS_R13(%rdi)
> + movq %r14, UC_MCONTEXT_GREGS_R14(%rdi)
> + movq %r15, UC_MCONTEXT_GREGS_R15(%rdi)
> + movq %rbp, UC_MCONTEXT_GREGS_RBP(%rdi)
> + movq %rbx, UC_MCONTEXT_GREGS_RBX(%rdi)
> +
> + /* Save argument registers (not strictly needed, but setcontext
> + restores them, so don't restore garbage). */
> + movq %r8, UC_MCONTEXT_GREGS_R8(%rdi)
> + movq %r9, UC_MCONTEXT_GREGS_R9(%rdi)
> + movq %rdi, UC_MCONTEXT_GREGS_RDI(%rdi)
> + movq %rsi, UC_MCONTEXT_GREGS_RSI(%rdi)
> + movq %rdx, UC_MCONTEXT_GREGS_RDX(%rdi)
> + movq %rax, UC_MCONTEXT_GREGS_RAX(%rdi)
> + movq %rcx, UC_MCONTEXT_GREGS_RCX(%rdi)
> +
> + /* Save fp state (not needed, except for setcontext not
> + restoring garbage). */
> + leaq UC_MCONTEXT_FPREGS_MEM(%rdi),%r8
> + movq %r8, UC_MCONTEXT_FPREGS_PTR(%rdi)
> + fnstenv (%r8)
> + stmxcsr FPREGS_OFFSET_MXCSR(%r8)
> +
> + leaq 8(%rsp), %rax /* exclude this call. */
> + movq %rax, UC_MCONTEXT_GREGS_RSP(%rdi)
> +
> + movq 0(%rsp), %rax
> + movq %rax, UC_MCONTEXT_GREGS_RIP(%rdi)
> +
> + xorq %rax, %rax
> + retq
> +
> +#ifdef __linux__
> + /* We do not need executable stack. */
> + .section .note.GNU-stack,"",@progbits
> +#endif
>
>
>
> _______________________________________________
> Libunwind-devel mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/libunwind-devel
>
--
Mosberger Consulting LLC, http://www.mosberger-consulting.com/