From 7b0c063f12f09e211391cd0f103e085f390d9f23 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 2 Dec 2015 12:11:06 +0100 Subject: Drop using _tlsbase and _tlstop in favor of access via NtCurrentTeb. * cygtls.h (_tlsbase): Remove. Replace throughout with NtCurrentTeb()->Tib.StackBase. (_tlstop): Remove. Replace throughout with NtCurrentTeb()->Tib.StackLimit. * dcrt0.cc (child_info_fork::alloc_stack): Move definition of local teb variable up to be used throughout. * include/cygwin/config.h (__getreent): Use inline function on both architectures. Signed-off-by: Corinna Vinschen --- winsup/cygwin/ChangeLog | 11 +++++++++++ winsup/cygwin/cygtls.h | 13 +------------ winsup/cygwin/dcrt0.cc | 28 +++++++++++++++------------- winsup/cygwin/fork.cc | 4 ++-- winsup/cygwin/include/cygwin/config.h | 17 ++++++++--------- winsup/cygwin/init.cc | 2 +- winsup/cygwin/wow64.cc | 6 +++--- 7 files changed, 41 insertions(+), 40 deletions(-) (limited to 'winsup') diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index f537983a8..c74d1ba60 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,14 @@ +2015-12-02 Corinna Vinschen + + * cygtls.h (_tlsbase): Remove. Replace throughout with + NtCurrentTeb()->Tib.StackBase. + (_tlstop): Remove. Replace throughout with + NtCurrentTeb()->Tib.StackLimit. + * dcrt0.cc (child_info_fork::alloc_stack): Move definition of local + teb variable up to be used throughout. + * include/cygwin/config.h (__getreent): Use inline function on both + architectures. + 2015-11-29 Corinna Vinschen * uinfo.cc (pwdgrp::fetch_account_from_windows): Only create 1-5-32-x diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index 527147324..42764c1cb 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -286,18 +286,7 @@ private: #include "cygerrno.h" #include "ntdll.h" -#ifdef __x86_64__ -/* When just using a "gs:X" asm for the x86_64 code, gcc wrongly creates - pc-relative instructions. However, NtCurrentTeb() is inline assembler - anyway, so using it here should be fast enough on x86_64. */ -#define _tlsbase (NtCurrentTeb()->Tib.StackBase) -#define _tlstop (NtCurrentTeb()->Tib.StackLimit) -#else -extern PVOID _tlsbase __asm__ ("%fs:4"); -extern PVOID _tlstop __asm__ ("%fs:8"); -#endif - -#define _my_tls (*((_cygtls *) ((char *)_tlsbase - CYGTLS_PADSIZE))) +#define _my_tls (*((_cygtls *) ((PBYTE) NtCurrentTeb()->Tib.StackBase - CYGTLS_PADSIZE))) extern _cygtls *_main_tls; extern _cygtls *_sig_tls; diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 3d293f609..7ec0ba3bf 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -411,15 +411,16 @@ child_info_fork::alloc_stack () { /* Make sure not to try a hard allocation if we have been forked off from the main thread of a Cygwin process which has been started from a 64 bit - parent. In that case the _tlsbase of the forked child is not the same - as the _tlsbase of the parent (== stackbottom), but only because the + parent. In that case the StackBase of the forked child is not the same + as the StackBase of the parent (== stackbottom), but only because the stack of the parent has been slightly rearranged. See comment in wow64_revert_to_original_stack for details. We check here if the parent stack fits into the child stack. */ - if (_tlsbase != stackbottom + PTEB teb = NtCurrentTeb (); + if (teb->Tib.StackBase != stackbottom && (!wincap.is_wow64 () - || stacktop < NtCurrentTeb ()->DeallocationStack - || stackbottom > _tlsbase)) + || stacktop < teb->DeallocationStack + || stackbottom > teb->Tib.StackBase)) { void *stack_ptr; size_t stacksize; @@ -432,10 +433,10 @@ child_info_fork::alloc_stack () stacksize = (PBYTE) stackbottom - (PBYTE) stackaddr; if (!VirtualAlloc (stackaddr, stacksize, MEM_RESERVE, PAGE_NOACCESS)) { - PTEB teb = NtCurrentTeb (); api_fatal ("fork: can't reserve memory for parent stack " "%p - %p, (child has %p - %p), %E", - stackaddr, stackbottom, teb->DeallocationStack, _tlsbase); + stackaddr, stackbottom, teb->DeallocationStack, + teb->Tib.StackBase); } /* Commit the area commited in parent. */ stacksize = (PBYTE) stackbottom - (PBYTE) stacktop; @@ -471,9 +472,10 @@ child_info_fork::alloc_stack () /* Fork has been called from main thread. Simply commit the region of the stack commited in the parent but not yet commited in the child and create new guardpages. */ - if (_tlstop > stacktop) + if (NtCurrentTeb()->Tib.StackLimit > stacktop) { - SIZE_T commitsize = (PBYTE) _tlstop - (PBYTE) stacktop; + SIZE_T commitsize = (PBYTE) NtCurrentTeb()->Tib.StackLimit + - (PBYTE) stacktop; if (!VirtualAlloc (stacktop, commitsize, MEM_COMMIT, PAGE_READWRITE)) api_fatal ("can't commit child memory for stack %p(%ly), %E", stacktop, commitsize); @@ -482,14 +484,14 @@ child_info_fork::alloc_stack () MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD)) api_fatal ("fork: couldn't allocate new stack guard page %p, %E", guardpage); - _tlstop = stacktop; + NtCurrentTeb()->Tib.StackLimit = stacktop; } stackaddr = 0; /* This only affects forked children of a process started from a native 64 bit process, but it doesn't hurt to do it unconditionally. Fix StackBase in the child to be the same as in the parent, so that the computation of _my_tls is correct. */ - _tlsbase = (PVOID) stackbottom; + teb->Tib.StackBase = (PVOID) stackbottom; } } @@ -918,8 +920,8 @@ dll_crt0_1 (void *) this step. */ if (fork_info->stackaddr) { - _tlsbase = (PVOID) fork_info->stackbottom; - _tlstop = (PVOID) fork_info->stacktop; + NtCurrentTeb()->Tib.StackBase = (PVOID) fork_info->stackbottom; + NtCurrentTeb()->Tib.StackLimit = (PVOID) fork_info->stacktop; } /* Not resetting _my_tls.incyg here because presumably fork will overwrite diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 084f8f026..78ae932d3 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -307,7 +307,7 @@ frok::parent (volatile char * volatile stack_here) ch.forker_finished = forker_finished; - ch.stackbottom = _tlsbase; + ch.stackbottom = NtCurrentTeb()->Tib.StackBase; ch.stackaddr = NtCurrentTeb ()->DeallocationStack; if (!ch.stackaddr) { @@ -315,7 +315,7 @@ frok::parent (volatile char * volatile stack_here) stack. If so, the entire stack is committed anyway and StackLimit points to the allocation address of the stack. Mark in guardsize that we must not set up guard pages. */ - ch.stackaddr = ch.stacktop = _tlstop; + ch.stackaddr = ch.stacktop = NtCurrentTeb()->Tib.StackLimit; ch.guardsize = (size_t) -1; } else diff --git a/winsup/cygwin/include/cygwin/config.h b/winsup/cygwin/include/cygwin/config.h index d3c68a502..58cff05b5 100644 --- a/winsup/cygwin/include/cygwin/config.h +++ b/winsup/cygwin/include/cygwin/config.h @@ -40,20 +40,19 @@ extern "C" { #ifdef _COMPILING_NEWLIB #ifdef __x86_64__ #include "../tlsoffsets64.h" -/* We would like to use just "%gs:8", but on x86_64 gcc uses pc-relative - addressing and translates "gs:8" into the wrong addressing mode. */ -static inline char *___getreent (void) +#else +#include "../tlsoffsets.h" +#endif +extern inline struct _reent *__getreent (void) { register char *ret; +#ifdef __x86_64__ __asm __volatile__ ("movq %%gs:8,%0" : "=r" (ret)); - return ret + tls_local_clib; -} -#define __getreent() ((struct _reent *) ___getreent()) #else -#include "../tlsoffsets.h" -extern char *_tlsbase __asm__ ("%fs:4"); -#define __getreent() (struct _reent *)(_tlsbase + tls_local_clib) + __asm __volatile__ ("movl %%fs:4,%0" : "=r" (ret)); #endif + return (struct _reent *) (ret + tls_local_clib); +} #endif /* _COMPILING_NEWLIB */ #ifdef __x86_64__ diff --git a/winsup/cygwin/init.cc b/winsup/cygwin/init.cc index 9dabf5f5a..e4ad59f3a 100644 --- a/winsup/cygwin/init.cc +++ b/winsup/cygwin/init.cc @@ -42,7 +42,7 @@ munge_threadfunc () if (!threadfunc_ix[0]) { char **peb; - char **top = (char **) _tlsbase; + char **top = (char **) NtCurrentTeb()->Tib.StackBase; for (peb = ebp, i = 0; peb < top && i < 7; peb++) if (*peb == search_for) threadfunc_ix[i++] = peb - ebp; diff --git a/winsup/cygwin/wow64.cc b/winsup/cygwin/wow64.cc index 18454af5f..240baa898 100644 --- a/winsup/cygwin/wow64.cc +++ b/winsup/cygwin/wow64.cc @@ -171,10 +171,10 @@ wow64_revert_to_original_stack (PVOID &allocationbase) accordingly, and return the new, 16 byte aligned address for the stack pointer. The second half of the stack move is done by the caller _dll_crt0. */ - _tlsbase = (char *) newbase; - _tlstop = (char *) newtop; + NtCurrentTeb()->Tib.StackBase = (char *) newbase; + NtCurrentTeb()->Tib.StackLimit = (char *) newtop; _main_tls = &_my_tls; - return PTR_ADD (_tlsbase, -16); + return PTR_ADD (NtCurrentTeb()->Tib.StackBase, -16); } /* Respawn WOW64 process. This is only called if we can't reuse the original -- cgit v1.2.3