Greetings, Attached patch implements getcontext for x86.
Motivation is the same as: http://lists.nongnu.org/archive/html/libunwind-devel/2008-06/msg00009.html This also fixes check-name-space on x86. Tested on Linux/86 with no new failures. Thanks, -- Paul Pluzhnikov diff --git a/include/libunwind-x86.h b/include/libunwind-x86.h index 84da6e9..65d42ba 100644 --- a/include/libunwind-x86.h +++ b/include/libunwind-x86.h @@ -163,12 +163,6 @@ unw_tdep_save_loc_t; /* On x86, 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 @@ -179,6 +173,9 @@ unw_tdep_proc_info_t; #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 e6e3b33..c110e76 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -227,7 +227,7 @@ libunwind_la_SOURCES_x86 = $(libunwind_la_SOURCES_x86_common) \ x86/Lcreate_addr_space.c x86/Lget_save_loc.c x86/Lglobal.c \ x86/Linit.c x86/Linit_local.c x86/Linit_remote.c \ x86/Lis_signal_frame.c x86/Lget_proc_info.c x86/Lregs.c \ - x86/Lresume.c x86/Lstep.c + x86/Lresume.c x86/Lstep.c x86/getcontext.S # The list of files that go into libunwind-x86: libunwind_x86_la_SOURCES_x86 = $(libunwind_la_SOURCES_x86_common) \ diff --git a/src/x86/getcontext.S b/src/x86/getcontext.S new file mode 100644 index 0000000..2f9b915 --- /dev/null +++ b/src/x86/getcontext.S @@ -0,0 +1,73 @@ +/* libunwind - a platform-independent unwind library + Copyright (C) 2009 Google, Inc + Contributed by Paul Pluzhnikov <[email protected]> + +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 "offsets.h" + +/* int _Ux86_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_getcontext + .type _Ux86_getcontext, @function +_Ux86_getcontext: + mov 4(%esp),%eax /* ucontext_t* */ + + /* EAX is not preserved. */ + movl $0, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EAX_OFF)(%eax) + + movl %ebx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EBX_OFF)(%eax) + movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_ECX_OFF)(%eax) + movl %edx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EDX_OFF)(%eax) + movl %edi, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EDI_OFF)(%eax) + movl %esi, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_ESI_OFF)(%eax) + movl %ebp, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EBP_OFF)(%eax) + + movl (%esp), %ecx + movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EIP_OFF)(%eax) + + leal 4(%esp), %ecx /* Exclude the return address. */ + movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_ESP_OFF)(%eax) + + /* glibc getcontext saves GS, but not FS */ + xorl %ecx, %ecx + movw %gs, %cx + movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FS_OFF)(%eax) + + leal LINUX_UC_FPREGS_MEM_OFF(%eax), %ecx + movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FPSTATE_OFF)(%eax) + fnstenv (%ecx) + fldenv (%ecx) + + xor %eax, %eax + ret + +#ifdef __linux__ + /* We do not need executable stack. */ + .section .note.GNU-stack,"",@progbits +#endif diff --git a/src/x86/offsets.h b/src/x86/offsets.h index 96f06d1..94307c1 100644 --- a/src/x86/offsets.h +++ b/src/x86/offsets.h @@ -9,6 +9,7 @@ #define LINUX_UC_STACK_OFF 0x08 #define LINUX_UC_MCONTEXT_OFF 0x14 #define LINUX_UC_SIGMASK_OFF 0x6c +#define LINUX_UC_FPREGS_MEM_OFF 0xec /* The struct sigcontext is located at an offset of 4 from the stack pointer in the signal frame. */ _______________________________________________ Libunwind-devel mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/libunwind-devel
