libunwind-devel
[Top][All Lists]
Advanced

[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/




reply via email to

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