I applied the patch with two changes: * Fixed trailing whitespace * Changed this hunk as follows:
+ /* glibc getcontext saves FS, but not GS */ + xorl %ecx, %ecx + movw %fs, %cx + movl %ecx, (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FS_OFF)(%eax) -Arun On Tue, Dec 22, 2009 at 6:58 PM, Paul Pluzhnikov <[email protected]>wrote: > 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
