Cygwin: config.h: stop including auto-generated tlsoffsets.h file

This was a hack to begin with.  Clean this mess up:

- Move definition of CYGTLS_PADSIZE to cygwin/config.h and drop
  local cygtls_padsize.h
- Rename CYGTLS_PADSIZE to __CYGTLS_PADSIZE__ to keep namespace
  clean.  Redefine as macro, rather than as const.
- Move struct _reent first in struct _cygtls to allow using
  __CYGTLS_PADSIZE__ as offset in __getreent().

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2022-01-27 12:39:57 +01:00
parent 2aa37fed76
commit d4fa3b4abb
12 changed files with 42 additions and 64 deletions

View File

@ -20,7 +20,7 @@ details. */
void void
_cygtls::call (DWORD (*func) (void *, void *), void *arg) _cygtls::call (DWORD (*func) (void *, void *), void *arg)
{ {
char buf[CYGTLS_PADSIZE]; char buf[__CYGTLS_PADSIZE__];
/* Initialize this thread's ability to respond to things like /* Initialize this thread's ability to respond to things like
SIGSEGV or SIGFPE. */ SIGSEGV or SIGFPE. */
exception protect; exception protect;

View File

@ -170,13 +170,13 @@ typedef uintptr_t __tlsstack_t;
class _cygtls class _cygtls
{ {
public: public:
/* Please keep these two declarations first */ /* Keep these two declarations first, keep local_clib first. */
struct _local_storage locals;
union union
{ {
struct _reent local_clib; struct _reent local_clib;
char __dontuse[8 * ((sizeof(struct _reent) + 4) / 8)]; char __dontuse[8 * ((sizeof(struct _reent) + 4) / 8)];
}; };
struct _local_storage locals;
/**/ /**/
void (*func) /*gentls_offsets*/(int, siginfo_t *, void *)/*gentls_offsets*/; void (*func) /*gentls_offsets*/(int, siginfo_t *, void *)/*gentls_offsets*/;
int saved_errno; int saved_errno;
@ -280,14 +280,13 @@ private:
}; };
#pragma pack(pop) #pragma pack(pop)
#include "cygtls_padsize.h"
/*gentls_offsets*/ /*gentls_offsets*/
#include "cygerrno.h" #include "cygerrno.h"
#include "ntdll.h" #include "ntdll.h"
#define _my_tls (*((_cygtls *) ((PBYTE) NtCurrentTeb()->Tib.StackBase - CYGTLS_PADSIZE))) #define _my_tls (*((_cygtls *) ((PBYTE) NtCurrentTeb()->Tib.StackBase \
- __CYGTLS_PADSIZE__)))
extern _cygtls *_main_tls; extern _cygtls *_main_tls;
extern _cygtls *_sig_tls; extern _cygtls *_sig_tls;

View File

@ -1,12 +0,0 @@
/* cygtls_padsize.h: Extra file to be included from utils.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
/* FIXME: Find some way to autogenerate this value */
#ifdef __x86_64__
const int CYGTLS_PADSIZE = 12800; /* Must be 16-byte aligned */
#else
const int CYGTLS_PADSIZE = 12700;
#endif

View File

@ -1103,7 +1103,7 @@ dll_crt0 (per_process *uptr)
} }
/* This must be called by anyone who uses LoadLibrary to load cygwin1.dll. /* This must be called by anyone who uses LoadLibrary to load cygwin1.dll.
You must have CYGTLS_PADSIZE bytes reserved at the bottom of the stack You must have __CYGTLS_PADSIZE__ bytes reserved at the bottom of the stack
calling this function, and that storage must not be overwritten until you calling this function, and that storage must not be overwritten until you
unload cygwin1.dll, as it is used for _my_tls. It is best to load unload cygwin1.dll, as it is used for _my_tls. It is best to load
cygwin1.dll before spawning any additional threads in your process. cygwin1.dll before spawning any additional threads in your process.

View File

@ -449,7 +449,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
res = 0; res = 0;
break; break;
case CW_CYGTLS_PADSIZE: case CW_CYGTLS_PADSIZE:
res = CYGTLS_PADSIZE; res = __CYGTLS_PADSIZE__;
break; break;
case CW_SET_DOS_FILE_WARNING: case CW_SET_DOS_FILE_WARNING:
res = 0; res = 0;

View File

@ -66,11 +66,11 @@ main(int argc, char **argv)
{ {
$struct *foo; $struct *foo;
# define foo_beg ((char *) foo) # define foo_beg ((char *) foo)
# define offset(f) ((unsigned)((int) (((char *) &(foo->f)) - foo_beg) - CYGTLS_PADSIZE)) # define offset(f) ((unsigned)((int) (((char *) &(foo->f)) - foo_beg) - __CYGTLS_PADSIZE__))
# define poffset(f) ((unsigned)(((char *) &(foo->f)) - ((char *) foo))) # define poffset(f) ((unsigned)(((char *) &(foo->f)) - ((char *) foo)))
EOF EOF
print TMP 'puts ("//;# autogenerated: Do not edit.\n");', "\n\n"; print TMP 'puts ("//;# autogenerated: Do not edit.\n");', "\n\n";
print TMP "printf (\"//; \$tls::start_offset = -%d;\\n\", CYGTLS_PADSIZE);\n"; print TMP "printf (\"//; \$tls::start_offset = -%d;\\n\", __CYGTLS_PADSIZE__);\n";
for my $f (@fields) { for my $f (@fields) {
print TMP ' printf ("//; $tls::', $f, ' = %d;\n", ', "offset($f));\n"; print TMP ' printf ("//; $tls::', $f, ' = %d;\n", ', "offset($f));\n";
print TMP ' printf ("//; $tls::p', $f, ' = %d;\n", ', "poffset($f));\n"; print TMP ' printf ("//; $tls::p', $f, ' = %d;\n", ', "poffset($f));\n";

View File

@ -1,7 +1,7 @@
Contributed by Max Kaehn Contributed by Max Kaehn
All cygwin threads have separate context in an object of class _cygtls. The All cygwin threads have separate context in an object of class _cygtls. The
storage for this object is kept on the stack in the bottom CYGTLS_PADSIZE storage for this object is kept on the stack in the bottom __CYGTLS_PADSIZE__
bytes. Each thread references the storage via the Thread Environment Block bytes. Each thread references the storage via the Thread Environment Block
(aka Thread Information Block), which Windows maintains for each user thread (aka Thread Information Block), which Windows maintains for each user thread
in the system, with the address in the FS segment register. The memory in the system, with the address in the FS segment register. The memory
@ -34,13 +34,13 @@ And accesses cygtls like this:
Initialization always goes through _cygtls::init_thread(). It works Initialization always goes through _cygtls::init_thread(). It works
in the following ways: in the following ways:
* In the main thread, _dll_crt0() provides CYGTLS_PADSIZE bytes on the stack * In the main thread, _dll_crt0() provides __CYGTLS_PADSIZE__ bytes on the stack
and passes them to initialize_main_tls(), which calls _cygtls::init_thread(). and passes them to initialize_main_tls(), which calls _cygtls::init_thread().
It then calls dll_crt0_1(), which terminates with cygwin_exit() rather than It then calls dll_crt0_1(), which terminates with cygwin_exit() rather than
by returning, so the storage never goes out of scope. by returning, so the storage never goes out of scope.
If you load cygwin1.dll dynamically from a non-cygwin application, it is If you load cygwin1.dll dynamically from a non-cygwin application, it is
vital that the bottom CYGTLS_PADSIZE bytes of the stack are not in use vital that the bottom __CYGTLS_PADSIZE__ bytes of the stack are not in use
before you call cygwin_dll_init(). See winsup/testsuite/cygload for before you call cygwin_dll_init(). See winsup/testsuite/cygload for
more information. more information.
@ -49,7 +49,7 @@ in the following ways:
- dll_entry() calls munge_threadfunc(), which grabs the function pointer - dll_entry() calls munge_threadfunc(), which grabs the function pointer
for the thread from the stack frame and substitutes threadfunc_fe(), for the thread from the stack frame and substitutes threadfunc_fe(),
- which then passes the original function pointer to _cygtls::call(), - which then passes the original function pointer to _cygtls::call(),
- which then allocates CYGTLS_PADSIZE bytes on the stack and hands them - which then allocates __CYGTLS_PADSIZE__ bytes on the stack and hands them
to call2(), to call2(),
- which allocates an exception_list object on the stack and hands it to - which allocates an exception_list object on the stack and hands it to
init_exceptions() (in exceptions.cc), which attaches it to the end of init_exceptions() (in exceptions.cc), which attaches it to the end of
@ -60,7 +60,7 @@ in the following ways:
Note that the padding isn't necessarily going to be just where the _cygtls Note that the padding isn't necessarily going to be just where the _cygtls
structure lives; it just makes sure there's enough room on the stack when the structure lives; it just makes sure there's enough room on the stack when the
CYGTLS_PADSIZE bytes down from there are overwritten. __CYGTLS_PADSIZE__ bytes down from there are overwritten.
Debugging Debugging

View File

@ -24,23 +24,14 @@ extern "C" {
version of a function that takes _REENT. This saves the overhead version of a function that takes _REENT. This saves the overhead
of a function call for what amounts to a simple computation. of a function call for what amounts to a simple computation.
The definition below is essentially equivalent to the one in cygtls.h This is the allocation size of the TLS area on the stack. Parts of
(&_my_tls.local_clib) however it uses a fixed precomputed the stack are in use by the OS, so we need to go a bit higher than
offset rather than dereferencing a field of a structure. what's actually required by the cygtls struct. The _reent struct is
right at the beginning of struct cygtls and always has to be. */
Including tlsoffets.h here in order to get this constant offset #define __CYGTLS_PADSIZE__ 12800 /* Must be 16-byte aligned */
tls_local_clib is a bit of a hack, but the alternative would require
dragging the entire definition of struct _cygtls (a large and complex
Cygwin internal data structure) into newlib. The machinery to
compute these offsets already exists for the sake of gendef so
we might as well just use it here. */
#if defined (_LIBC) || defined (__INSIDE_CYGWIN__) #if defined (_LIBC) || defined (__INSIDE_CYGWIN__)
#ifdef __x86_64__
#include "../tlsoffsets64.h"
#else
#include "../tlsoffsets.h"
#endif
__attribute__((__gnu_inline__)) __attribute__((__gnu_inline__))
extern inline struct _reent *__getreent (void) extern inline struct _reent *__getreent (void)
{ {
@ -50,7 +41,7 @@ extern inline struct _reent *__getreent (void)
#else #else
__asm __volatile__ ("movl %%fs:4,%0" : "=r" (ret)); __asm __volatile__ ("movl %%fs:4,%0" : "=r" (ret));
#endif #endif
return (struct _reent *) (ret + tls_local_clib); return (struct _reent *) (ret - __CYGTLS_PADSIZE__);
} }
#endif /* _LIBC || __INSIDE_CYGWIN__ */ #endif /* _LIBC || __INSIDE_CYGWIN__ */

View File

@ -92,8 +92,8 @@ dll_entry (HANDLE h, DWORD reason, void *static_load)
initialized to NULL, so subsequent calls to locale-specific functions initialized to NULL, so subsequent calls to locale-specific functions
will always fall back to __global_locale, rather then crash due to will always fall back to __global_locale, rather then crash due to
_REENT->_locale having an arbitrary value. */ _REENT->_locale having an arbitrary value. */
alloca_dummy = alloca (CYGTLS_PADSIZE); alloca_dummy = alloca (__CYGTLS_PADSIZE__);
ZeroMemory (alloca_dummy, CYGTLS_PADSIZE); ZeroMemory (alloca_dummy, __CYGTLS_PADSIZE__);
memcpy (_REENT, _GLOBAL_REENT, sizeof (struct _reent)); memcpy (_REENT, _GLOBAL_REENT, sizeof (struct _reent));
dll_crt0_0 (); dll_crt0_0 ();

View File

@ -415,7 +415,7 @@ pthread_wrapper (PVOID arg)
SetThreadStackGuarantee (&wrapper_arg.guardsize); SetThreadStackGuarantee (&wrapper_arg.guardsize);
} }
/* Initialize new _cygtls. */ /* Initialize new _cygtls. */
_my_tls.init_thread (wrapper_arg.stackbase - CYGTLS_PADSIZE, _my_tls.init_thread (wrapper_arg.stackbase - __CYGTLS_PADSIZE__,
(DWORD (*)(void*, void*)) wrapper_arg.func); (DWORD (*)(void*, void*)) wrapper_arg.func);
#ifdef __i386__ #ifdef __i386__
/* Copy exception list over to new stack. I'm not quite sure how the /* Copy exception list over to new stack. I'm not quite sure how the
@ -458,7 +458,7 @@ pthread_wrapper (PVOID arg)
movq 8(%%rbx), %%r13 # Load thread arg into r13 \n\ movq 8(%%rbx), %%r13 # Load thread arg into r13 \n\
movq 16(%%rbx), %%rcx # Load stackaddr into rcx \n\ movq 16(%%rbx), %%rcx # Load stackaddr into rcx \n\
movq 24(%%rbx), %%rsp # Load stackbase into rsp \n\ movq 24(%%rbx), %%rsp # Load stackbase into rsp \n\
subq %[CYGTLS], %%rsp # Subtract CYGTLS_PADSIZE \n\ subq %[CYGTLS], %%rsp # Subtract __CYGTLS_PADSIZE__ \n\
# (here we are 16 bytes aligned)\n\ # (here we are 16 bytes aligned)\n\
subq $32, %%rsp # Subtract another 32 bytes \n\ subq $32, %%rsp # Subtract another 32 bytes \n\
# (shadow space for arg regs) \n\ # (shadow space for arg regs) \n\
@ -474,7 +474,7 @@ pthread_wrapper (PVOID arg)
movq %%r13, %%rcx # Move thread arg to 1st arg reg\n\ movq %%r13, %%rcx # Move thread arg to 1st arg reg\n\
call *%%r12 # Call thread func \n" call *%%r12 # Call thread func \n"
: : [WRAPPER_ARG] "o" (wrapper_arg), : : [WRAPPER_ARG] "o" (wrapper_arg),
[CYGTLS] "i" (CYGTLS_PADSIZE)); [CYGTLS] "i" (__CYGTLS_PADSIZE__));
#else #else
__asm__ ("\n\ __asm__ ("\n\
leal %[WRAPPER_ARG], %%ebx # Load &wrapper_arg into ebx \n\ leal %[WRAPPER_ARG], %%ebx # Load &wrapper_arg into ebx \n\
@ -482,7 +482,7 @@ pthread_wrapper (PVOID arg)
movl 4(%%ebx), %%ecx # Load thread arg into ecx \n\ movl 4(%%ebx), %%ecx # Load thread arg into ecx \n\
movl 8(%%ebx), %%edx # Load stackaddr into edx \n\ movl 8(%%ebx), %%edx # Load stackaddr into edx \n\
movl 12(%%ebx), %%ebx # Load stackbase into ebx \n\ movl 12(%%ebx), %%ebx # Load stackbase into ebx \n\
subl %[CYGTLS], %%ebx # Subtract CYGTLS_PADSIZE \n\ subl %[CYGTLS], %%ebx # Subtract __CYGTLS_PADSIZE__ \n\
subl $4, %%ebx # Subtract another 4 bytes \n\ subl $4, %%ebx # Subtract another 4 bytes \n\
movl %%ebx, %%esp # Set esp \n\ movl %%ebx, %%esp # Set esp \n\
xorl %%ebp, %%ebp # Set ebp to 0 \n\ xorl %%ebp, %%ebp # Set ebp to 0 \n\
@ -505,7 +505,7 @@ pthread_wrapper (PVOID arg)
popl %%eax # Pop thread_func address \n\ popl %%eax # Pop thread_func address \n\
call *%%eax # Call thread func \n" call *%%eax # Call thread func \n"
: : [WRAPPER_ARG] "o" (wrapper_arg), : : [WRAPPER_ARG] "o" (wrapper_arg),
[CYGTLS] "i" (CYGTLS_PADSIZE)); [CYGTLS] "i" (__CYGTLS_PADSIZE__));
#endif #endif
/* pthread::thread_init_wrapper calls pthread::exit, which /* pthread::thread_init_wrapper calls pthread::exit, which
in turn calls ExitThread, so we should never arrive here. */ in turn calls ExitThread, so we should never arrive here. */

View File

@ -1,12 +1,12 @@
//;# autogenerated: Do not edit. //;# autogenerated: Do not edit.
//; $tls::start_offset = -12800; //; $tls::start_offset = -12800;
//; $tls::locals = -12800; //; $tls::local_clib = -12800;
//; $tls::plocals = 0; //; $tls::plocal_clib = 0;
//; $tls::local_clib = -10624; //; $tls::__dontuse = -12800;
//; $tls::plocal_clib = 2176; //; $tls::p__dontuse = 0;
//; $tls::__dontuse = -10624; //; $tls::locals = -11488;
//; $tls::p__dontuse = 2176; //; $tls::plocals = 1312;
//; $tls::func = -9312; //; $tls::func = -9312;
//; $tls::pfunc = 3488; //; $tls::pfunc = 3488;
//; $tls::saved_errno = -9304; //; $tls::saved_errno = -9304;
@ -63,12 +63,12 @@
//; $tls::pinitialized = 7192; //; $tls::pinitialized = 7192;
//; __DATA__ //; __DATA__
#define tls_locals (-12800) #define tls_local_clib (-12800)
#define tls_plocals (0) #define tls_plocal_clib (0)
#define tls_local_clib (-10624) #define tls___dontuse (-12800)
#define tls_plocal_clib (2176) #define tls_p__dontuse (0)
#define tls___dontuse (-10624) #define tls_locals (-11488)
#define tls_p__dontuse (2176) #define tls_plocals (1312)
#define tls_func (-9312) #define tls_func (-9312)
#define tls_pfunc (3488) #define tls_pfunc (3488)
#define tls_saved_errno (-9304) #define tls_saved_errno (-9304)

View File

@ -24,7 +24,7 @@ details. */
#include "sys/strace.h" #include "sys/strace.h"
#include "sys/cygwin.h" #include "sys/cygwin.h"
#include "cygwin/version.h" #include "cygwin/version.h"
#include "cygtls_padsize.h" #include "cygwin/config.h"
#include "gcc_seh.h" #include "gcc_seh.h"
#include "path.h" #include "path.h"
#undef cygwin_internal #undef cygwin_internal
@ -1218,7 +1218,7 @@ main (int argc, char **argv)
This is required to make sure cygwin_internal calls into Cygwin work This is required to make sure cygwin_internal calls into Cygwin work
reliably. This problem has been noticed under AllocationPreference reliably. This problem has been noticed under AllocationPreference
registry setting to 0x100000 (TOP_DOWN). */ registry setting to 0x100000 (TOP_DOWN). */
char buf[CYGTLS_PADSIZE]; char buf[__CYGTLS_PADSIZE__];
RtlSecureZeroMemory (buf, sizeof (buf)); RtlSecureZeroMemory (buf, sizeof (buf));
exit (main2 (argc, argv)); exit (main2 (argc, argv));