aboutsummaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2022-02-02 17:27:34 +0100
committerCorinna Vinschen <corinna@vinschen.de>2022-05-12 22:00:25 +0200
commitccf1638e8ec8880f5b2282084a1e34bbb61f9051 (patch)
tree7a89407321650e562cc4d661808724661eeb6f96 /winsup
parentb5dcb1e5e39f16a8aa207f48f2bd889348110d25 (diff)
downloadnewlib-ccf1638e8ec8880f5b2282084a1e34bbb61f9051.zip
newlib-ccf1638e8ec8880f5b2282084a1e34bbb61f9051.tar.gz
newlib-ccf1638e8ec8880f5b2282084a1e34bbb61f9051.tar.bz2
Cygwin: revamp TLS offsets computation
- convert gentls_offsets to a shell script, only running the target compiler and gawk. - Simplify cygtls.h. The new gentls_offsets script only requires two lines with the "public:" keyword as markers. The comments are not used anymore, the output is a preprocesses file without comments. Align Makefile rules accordingly. - Rather than generating perl variables and C #defines, just generate .ecu statements and .include the TLS offsets file right from the generated assembler file sigfe.s. It's the only place we really need (some of) the offsets. - Drop the target-specific name of the TLS offsets file and generate it on the fly in the build dir. Fix configure and Makefile rules accordingly. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'winsup')
-rw-r--r--winsup/configure.ac2
-rw-r--r--winsup/cygwin/Makefile.am14
-rw-r--r--winsup/cygwin/cygtls.h28
-rwxr-xr-xwinsup/cygwin/gendef154
-rwxr-xr-xwinsup/cygwin/gentls_offsets178
-rw-r--r--winsup/cygwin/tlsoffsets-x86_64.h125
6 files changed, 169 insertions, 332 deletions
diff --git a/winsup/configure.ac b/winsup/configure.ac
index 5d83c23..634493e 100644
--- a/winsup/configure.ac
+++ b/winsup/configure.ac
@@ -67,7 +67,6 @@ esac
DLL_ENTRY="dll_entry"
DIN_FILE="${target_cpu}.din"
-TLSOFFSETS_H="tlsoffsets-${target_cpu}.h"
case "$target_cpu" in
x86_64) ;;
@@ -76,7 +75,6 @@ esac
AC_SUBST(DLL_ENTRY)
AC_SUBST(DIN_FILE)
-AC_SUBST(TLSOFFSETS_H)
AM_CONDITIONAL(TARGET_X86_64, [test $target_cpu = "x86_64"])
diff --git a/winsup/cygwin/Makefile.am b/winsup/cygwin/Makefile.am
index 5fd87c6..fe17a5b 100644
--- a/winsup/cygwin/Makefile.am
+++ b/winsup/cygwin/Makefile.am
@@ -45,7 +45,6 @@ DBG_DLL_NAME=cygwin1.dbg
NEW_DLL_NAME=new-cygwin1.dll
DIN_FILE=@DIN_FILE@
DEF_FILE=cygwin.def
-TLSOFFSETS_H=@TLSOFFSETS_H@
LIB_NAME=libcygwin.a
TEST_LIB_NAME=libcygwin0.a
@@ -386,8 +385,8 @@ localtime.patched.c: tzcode/localtime.c tzcode/localtime.c.patch
$(srcdir)/devices.cc: gendevices devices.in devices.h
$(wordlist 1,2,$^) $@
-$(srcdir)/$(TLSOFFSETS_H): gentls_offsets cygtls.h
- $^ $@ $(target_cpu) $(CC) $(AM_CFLAGS) -c || rm $@
+tlsoffsets: gentls_offsets cygtls.h
+ $(AM_V_GEN)CXXCOMPILE="$(CXXCOMPILE)" $^ $@
BUILT_SOURCES = \
child_info_magic.h \
@@ -609,10 +608,10 @@ $(NEW_DLL_NAME): $(PRE_DLL_NAME) $(DBG_DLL_NAME)
# cygwin import library
toolopts=--cpu=@target_cpu@ --ar=@AR@ --as=@AS@ --nm=@NM@ --objcopy=@OBJCOPY@
-$(DEF_FILE): gendef $(srcdir)/$(TLSOFFSETS_H) $(DIN_FILE) common.din
- $(AM_V_GEN)$(srcdir)/gendef --cpu=@target_cpu@ --output-def=$(DEF_FILE) --tlsoffsets=$(srcdir)/$(TLSOFFSETS_H) $(srcdir)/$(DIN_FILE) $(srcdir)/common.din
+$(DEF_FILE): gendef $(DIN_FILE) common.din
+ $(AM_V_GEN)$(srcdir)/gendef --cpu=@target_cpu@ --output-def=$(DEF_FILE) $(srcdir)/$(DIN_FILE) $(srcdir)/common.din
-sigfe.s: $(DEF_FILE)
+sigfe.s: $(DEF_FILE) tlsoffsets
@[ -s $@ ] || \
{ rm -f $(DEF_FILE); $(MAKE) -s -j1 $(DEF_FILE); }; \
[ -s $@ ] && touch $@
@@ -680,9 +679,10 @@ clean-local:
-rm -f $(PRE_DLL_NAME) $(DBG_DLL_NAME) $(NEW_DLL_NAME)
-rm -f $(LIB_NAME) $(TEST_LIB_NAME) $(SUBLIBS)
-rm -f version.cc
+ -rm -f tlsoffsets
maintainer-clean-local:
- -rm -f $(srcdir)/$(TLSOFFSETS_H) $(srcdir)/devices.cc
+ -rm -f $(srcdir)/devices.cc
#
# install
diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h
index 7ee6165..c4702e8 100644
--- a/winsup/cygwin/cygtls.h
+++ b/winsup/cygwin/cygtls.h
@@ -152,33 +152,22 @@ typedef struct struct_waitq
HANDLE thread_ev;
} waitq;
-/* Changes to the below structure may require acompanying changes to the very
- simple parser in the perl script 'gentls_offsets' (<<-- start parsing here).
- The union in this structure is used to force alignment between the version
- of the compiler used to generate tlsoffsets.h and the cygwin cross compiler.
-*/
-
-/*gentls_offsets*/
+/* Changes to the below structure may require acompanying changes to the
+ gawk parser in the shell script 'gentls_offsets' */
extern "C" int __sjfault (jmp_buf);
extern "C" int __ljfault (jmp_buf, int);
-/*gentls_offsets*/
-
typedef uintptr_t __tlsstack_t;
class _cygtls
{
-public:
- /* Keep these two declarations first, keep local_clib first. */
- union
- {
- struct _reent local_clib;
- char __dontuse[8 * ((sizeof(struct _reent) + 4) / 8)];
- };
+public: /* Do NOT remove this public: line, it's a marker for gentls_offsets. */
+ /* offsetoff (class _cygtls, local_clib) *must* be 0. */
+ struct _reent local_clib;
struct _local_storage locals;
/**/
- void (*func) /*gentls_offsets*/(int, siginfo_t *, void *)/*gentls_offsets*/;
+ void (*func) (int, siginfo_t *, void *);
int saved_errno;
int sa_flags;
sigset_t oldmask;
@@ -209,7 +198,7 @@ public:
__tlsstack_t stack[TLS_STACK_SIZE];
unsigned initialized;
- /*gentls_offsets*/
+public: /* Do NOT remove this public: line, it's a marker for gentls_offsets. */
void init_thread (void *, DWORD (*) (void *, void *));
static void call (DWORD (*) (void *, void *), void *);
void remove (DWORD);
@@ -276,12 +265,9 @@ public:
private:
void __reg3 call2 (DWORD (*) (void *, void *), void *, void *);
void remove_pending_sigs ();
- /*gentls_offsets*/
};
#pragma pack(pop)
-/*gentls_offsets*/
-
#include "cygerrno.h"
#include "ntdll.h"
diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef
index 431ec67..779cdcf 100755
--- a/winsup/cygwin/gendef
+++ b/winsup/cygwin/gendef
@@ -14,16 +14,13 @@ sub cleanup(@);
my $cpu;
my $output_def;
-my $tls_offsets;
-GetOptions('cpu=s'=>\$cpu, 'output-def=s'=>\$output_def, 'tlsoffsets=s'=>\$tls_offsets);
+GetOptions('cpu=s'=>\$cpu, 'output-def=s'=>\$output_def);
$main::first = 0;
-if (!defined($cpu) || !defined($output_def) || !defined($tls_offsets)) {
+if (!defined($cpu) || !defined($output_def)) {
die "$0: missing required option\n";
}
-require $tls_offsets;
-
my $is64bit = $cpu eq 'x86_64';
my $sym_prefix = $is64bit ? '' : '_';
@@ -125,16 +122,17 @@ EOF
if (!$main::first++) {
if ($is64bit) {
$res = <<EOF . longjmp () . $res;
+ .include "tlsoffsets"
.text
.seh_proc _sigfe_maybe
_sigfe_maybe: # stack is aligned on entry!
.seh_endprologue
movq %gs:8,%r10 # location of bottom of stack
- leaq $tls::initialized(%r10),%r11 # where we will be looking
+ leaq _cygtls.initialized(%r10),%r11 # where we will be looking
cmpq %r11,%rsp # stack loc > than tls
jge 0f # yep. we don't have a tls.
- movl $tls::initialized(%r10),%r11d
+ movl _cygtls.initialized(%r10),%r11d
cmpl \$0xc763173f,%r11d # initialized?
je 1f
0: ret
@@ -145,19 +143,19 @@ _sigfe: # stack is aligned on entry!
.seh_endprologue
movq %gs:8,%r10 # location of bottom of stack
1: movl \$1,%r11d # potential lock value
- xchgl %r11d,$tls::stacklock(%r10) # see if we can grab it
- movl %r11d,$tls::spinning(%r10) # flag if we are waiting for lock
+ xchgl %r11d,_cygtls.stacklock(%r10) # see if we can grab it
+ movl %r11d,_cygtls.spinning(%r10) # flag if we are waiting for lock
testl %r11d,%r11d # it will be zero
jz 2f # if so
pause
jmp 1b # loop
2: movq \$8,%rax # have the lock, now increment the
- xaddq %rax,$tls::stackptr(%r10) # stack pointer and get pointer
+ xaddq %rax,_cygtls.stackptr(%r10) # stack pointer and get pointer
leaq _sigbe(%rip),%r11 # new place to return to
xchgq %r11,8(%rsp) # exchange with real return value
movq %r11,(%rax) # store real return value on alt stack
- incl $tls::incyg(%r10)
- decl $tls::stacklock(%r10) # remove lock
+ incl _cygtls.incyg(%r10)
+ decl _cygtls.stacklock(%r10) # remove lock
popq %rax # pop real function address from stack
jmp *%rax # and jmp to it
.seh_endproc
@@ -169,17 +167,17 @@ _sigbe: # return here after cygwin syscall
.seh_endprologue
movq %gs:8,%r10 # address of bottom of tls
1: movl \$1,%r11d # potential lock value
- xchgl %r11d,$tls::stacklock(%r10) # see if we can grab it
- movl %r11d,$tls::spinning(%r10) # flag if we are waiting for lock
+ xchgl %r11d,_cygtls.stacklock(%r10) # see if we can grab it
+ movl %r11d,_cygtls.spinning(%r10) # flag if we are waiting for lock
testl %r11d,%r11d # it will be zero
jz 2f # if so
pause
jmp 1b # and loop
2: movq \$-8,%r11 # now decrement aux stack
- xaddq %r11,$tls::stackptr(%r10) # and get pointer
+ xaddq %r11,_cygtls.stackptr(%r10) # and get pointer
movq -8(%r11),%r11 # get return address from signal stack
- decl $tls::incyg(%r10)
- decl $tls::stacklock(%r10) # release lock
+ decl _cygtls.incyg(%r10)
+ decl _cygtls.stacklock(%r10) # release lock
jmp *%r11 # "return" to caller
.seh_endproc
@@ -248,29 +246,29 @@ sigdelayed:
.seh_endprologue
movq %gs:8,%r12 # get tls
- movl $tls::saved_errno(%r12),%r15d # temporarily save saved_errno
- movq \$$tls::start_offset,%rcx # point to beginning of tls block
+ movl _cygtls.saved_errno(%r12),%r15d # temporarily save saved_errno
+ movq \$_cygtls.start_offset,%rcx # point to beginning of tls block
addq %r12,%rcx # and store as first arg to method
call _ZN7_cygtls19call_signal_handlerEv # call handler
1: movl \$1,%r11d # potential lock value
- xchgl %r11d,$tls::stacklock(%r12) # see if we can grab it
- movl %r11d,$tls::spinning(%r12) # flag if we are waiting for lock
+ xchgl %r11d,_cygtls.stacklock(%r12) # see if we can grab it
+ movl %r11d,_cygtls.spinning(%r12) # flag if we are waiting for lock
testl %r11d,%r11d # it will be zero
jz 2f # if so
pause
jmp 1b # and loop
2: testl %r15d,%r15d # was saved_errno < 0
jl 3f # yup. ignore it
- movq $tls::errno_addr(%r12),%r11
+ movq _cygtls.errno_addr(%r12),%r11
movl %r15d,(%r11)
3: movq \$-8,%r11 # now decrement aux stack
- xaddq %r11,$tls::stackptr(%r12) # and get pointer
+ xaddq %r11,_cygtls.stackptr(%r12) # and get pointer
xorq %r10,%r10
xchgq %r10,-8(%r11) # get return address from signal stack
xorl %r11d,%r11d
- movl %r11d,$tls::incyg(%r12)
- movl %r11d,$tls::stacklock(%r12) # unlock
+ movl %r11d,_cygtls.incyg(%r12)
+ movl %r11d,_cygtls.stacklock(%r12) # unlock
movdqa 0x20(%rsp),%xmm0
movdqa 0x30(%rsp),%xmm1
movdqa 0x40(%rsp),%xmm2
@@ -320,7 +318,7 @@ _sigdelayed_end:
_ZN7_cygtls3popEv:
.seh_endprologue
movq \$-8,%r11
- xaddq %r11,$tls::pstackptr(%rcx)
+ xaddq %r11,_cygtls.pstackptr(%rcx)
movq -8(%r11),%rax
ret
.seh_endproc
@@ -334,7 +332,7 @@ _ZN7_cygtls4lockEv:
.seh_endprologue
movq %rcx,%r12
1: movl \$1,%r11d
- xchgl %r11d,$tls::pstacklock(%r12)
+ xchgl %r11d,_cygtls.pstacklock(%r12)
testl %r11d,%r11d
jz 2f
pause
@@ -348,7 +346,7 @@ _ZN7_cygtls4lockEv:
.seh_proc _ZN7_cygtls6unlockEv
_ZN7_cygtls6unlockEv:
.seh_endprologue
- decl $tls::pstacklock(%rcx)
+ decl _cygtls.pstacklock(%rcx)
ret
.seh_endproc
@@ -357,7 +355,7 @@ _ZN7_cygtls6unlockEv:
.seh_proc _ZN7_cygtls6lockedEv
_ZN7_cygtls6lockedEv:
.seh_endprologue
- movl $tls::pstacklock(%rcx),%eax
+ movl _cygtls.pstacklock(%rcx),%eax
ret
.seh_endproc
@@ -370,21 +368,21 @@ stabilize_sig_stack:
.seh_endprologue
movq %gs:8,%r12
1: movl \$1,%r10d
- xchgl %r10d,$tls::stacklock(%r12)
- movl %r10d,$tls::spinning(%r12) # flag if we are waiting for lock
+ xchgl %r10d,_cygtls.stacklock(%r12)
+ movl %r10d,_cygtls.spinning(%r12) # flag if we are waiting for lock
testl %r10d,%r10d
jz 2f
pause
jmp 1b
-2: incl $tls::incyg(%r12)
- cmpl \$0,$tls::sig(%r12)
+2: incl _cygtls.incyg(%r12)
+ cmpl \$0,_cygtls.sig(%r12)
jz 3f
- decl $tls::stacklock(%r12) # unlock
- movq \$$tls::start_offset,%rcx # point to beginning
+ decl _cygtls.stacklock(%r12) # unlock
+ movq \$_cygtls.start_offset,%rcx # point to beginning
addq %r12,%rcx # of tls block
call _ZN7_cygtls19call_signal_handlerEv
jmp 1b
-3: decl $tls::incyg(%r12)
+3: decl _cygtls.incyg(%r12)
addq \$0x20,%rsp
movq %r12,%r11 # return tls addr in r11
popq %r12
@@ -399,11 +397,11 @@ __sigfe_maybe:
pushl %ebx
pushl %edx
movl %fs:4,%ebx # location of bottom of stack
- addl \$$tls::initialized,%ebx # where we will be looking
+ addl \$_cygtls.initialized,%ebx # where we will be looking
cmpl %ebx,%esp # stack loc > than tls
jge 0f # yep. we don't have a tls.
- subl \$$tls::initialized,%ebx # where we will be looking
- movl $tls::initialized(%ebx),%eax
+ subl \$_cygtls.initialized,%ebx # where we will be looking
+ movl _cygtls.initialized(%ebx),%eax
cmpl \$0xc763173f,%eax # initialized?
je 1f
0: popl %edx
@@ -415,19 +413,19 @@ __sigfe:
pushl %edx
movl %fs:4,%ebx # location of bottom of stack
1: movl \$1,%eax # potential lock value
- xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it
- movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
+ xchgl %eax,_cygtls.stacklock(%ebx) # see if we can grab it
+ movl %eax,_cygtls.spinning(%ebx) # flag if we are waiting for lock
testl %eax,%eax # it will be zero
jz 2f # if so
call _yield # should be a short-time thing, so
jmp 1b # sleep and loop
2: movl \$4,%eax # have the lock, now increment the
- xadd %eax,$tls::stackptr(%ebx) # stack pointer and get pointer
+ xadd %eax,_cygtls.stackptr(%ebx) # stack pointer and get pointer
leal __sigbe,%edx # new place to return to
xchgl %edx,12(%esp) # exchange with real return value
movl %edx,(%eax) # store real return value on alt stack
- incl $tls::incyg(%ebx)
- decl $tls::stacklock(%ebx) # remove lock
+ incl _cygtls.incyg(%ebx)
+ decl _cygtls.stacklock(%ebx) # remove lock
popl %edx # restore saved value
popl %ebx
ret
@@ -438,18 +436,18 @@ __sigbe: # return here after cygwin syscall
pushl %ebx # tls pointer
1: movl %fs:4,%ebx # address of bottom of tls
movl \$1,%eax # potential lock value
- xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it
- movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
+ xchgl %eax,_cygtls.stacklock(%ebx) # see if we can grab it
+ movl %eax,_cygtls.spinning(%ebx) # flag if we are waiting for lock
testl %eax,%eax # it will be zero
jz 2f # if so
call _yield # sleep
jmp 1b # and loop
2: movl \$-4,%eax # now decrement aux stack
- xadd %eax,$tls::stackptr(%ebx) # and get pointer
+ xadd %eax,_cygtls.stackptr(%ebx) # and get pointer
movl -4(%eax),%eax # get return address from signal stack
xchgl %eax,4(%esp) # swap return address with saved eax
- decl $tls::incyg(%ebx)
- decl $tls::stacklock(%ebx) # release lock
+ decl _cygtls.incyg(%ebx)
+ decl _cygtls.stacklock(%ebx) # release lock
popl %ebx
ret
@@ -477,16 +475,16 @@ _sigdelayed:
movdqu %xmm1,0x10(%esp)
movdqu %xmm0,(%esp)
movl %fs:4,%ebx # get tls
- pushl $tls::saved_errno(%ebx) # saved errno
+ pushl _cygtls.saved_errno(%ebx) # saved errno
- movl \$$tls::start_offset,%eax # point to beginning
+ movl \$_cygtls.start_offset,%eax # point to beginning
addl %ebx,%eax # of tls block
call __ZN7_cygtls19call_signal_handlerEv\@4 # call handler
movl %fs:4,%ebx # reget tls
1: movl \$1,%eax # potential lock value
- xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it
- movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
+ xchgl %eax,_cygtls.stacklock(%ebx) # see if we can grab it
+ movl %eax,_cygtls.spinning(%ebx) # flag if we are waiting for lock
testl %eax,%eax # it will be zero
jz 2f # if so
call _yield # sleep
@@ -494,16 +492,16 @@ _sigdelayed:
2: popl %edx # saved errno
testl %edx,%edx # Is it < 0
jl 3f # yup. ignore it
- movl $tls::errno_addr(%ebx),%eax
+ movl _cygtls.errno_addr(%ebx),%eax
movl %edx,(%eax)
3: movl \$-4,%eax # now decrement aux stack
- xadd %eax,$tls::stackptr(%ebx) # and get pointer
+ xadd %eax,_cygtls.stackptr(%ebx) # and get pointer
xorl %ebp,%ebp
xchgl %ebp,-4(%eax) # get return address from signal stack
xchgl %ebp,0xa0(%esp) # store real return address
leave: xorl %eax,%eax
- movl %eax,$tls::incyg(%ebx)
- movl %eax,$tls::stacklock(%ebx) # unlock
+ movl %eax,_cygtls.incyg(%ebx)
+ movl %eax,_cygtls.stacklock(%ebx) # unlock
movdqu (%esp),%xmm0
movdqu 0x10(%esp),%xmm1
@@ -530,7 +528,7 @@ __ZN7_cygtls3popEv\@4:
1: pushl %ebx
movl %eax,%ebx # this
movl \$-4,%eax
- xadd %eax,$tls::pstackptr(%ebx)
+ xadd %eax,_cygtls.pstackptr(%ebx)
movl -4(%eax),%eax
popl %ebx
ret
@@ -541,7 +539,7 @@ __ZN7_cygtls4lockEv\@4:
pushl %ebx
movl %eax,%ebx
1: movl \$1,%eax
- xchgl %eax,$tls::pstacklock(%ebx)
+ xchgl %eax,_cygtls.pstacklock(%ebx)
testl %eax,%eax
jz 2f
call _yield
@@ -552,33 +550,33 @@ __ZN7_cygtls4lockEv\@4:
# _cygtls::unlock
.global __ZN7_cygtls6unlockEv\@4
__ZN7_cygtls6unlockEv\@4:
- decl $tls::pstacklock(%eax)
+ decl _cygtls.pstacklock(%eax)
ret
.global __ZN7_cygtls6lockedEv
__ZN7_cygtls6lockedEv:
- movl $tls::pstacklock(%eax),%eax
+ movl _cygtls.pstacklock(%eax),%eax
ret
.extern __ZN7_cygtls19call_signal_handlerEv\@4
stabilize_sig_stack:
movl %fs:4,%ebx
1: movl \$1,%eax
- xchgl %eax,$tls::stacklock(%ebx)
- movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
+ xchgl %eax,_cygtls.stacklock(%ebx)
+ movl %eax,_cygtls.spinning(%ebx) # flag if we are waiting for lock
testl %eax,%eax
jz 2f
call _yield
jmp 1b
-2: incl $tls::incyg(%ebx)
- cmpl \$0,$tls::sig(%ebx)
+2: incl _cygtls.incyg(%ebx)
+ cmpl \$0,_cygtls.sig(%ebx)
jz 3f
- decl $tls::stacklock(%ebx) # unlock
- movl \$$tls::start_offset,%eax # point to beginning
+ decl _cygtls.stacklock(%ebx) # unlock
+ movl \$_cygtls.start_offset,%eax # point to beginning
addl %ebx,%eax # of tls block
call __ZN7_cygtls19call_signal_handlerEv\@4
jmp 1b
-3: decl $tls::incyg(%ebx)
+3: decl _cygtls.incyg(%ebx)
ret
EOF
}
@@ -644,9 +642,9 @@ setjmp:
.seh_pushreg %rcx
call stabilize_sig_stack # returns tls in r11
popq %rcx
- movq $tls::stackptr(%r11),%r10
+ movq _cygtls.stackptr(%r11),%r10
movq %r10,(%rcx)
- decl $tls::stacklock(%r11)
+ decl _cygtls.stacklock(%r11)
xorl %eax,%eax
ret
.seh_endproc
@@ -682,10 +680,10 @@ longjmp:
popq %rcx
movl %r12d,%eax # restore return value
movq (%rcx),%r10 # get old signal stack
- movq %r10,$tls::stackptr(%r11) # restore
- decl $tls::stacklock(%r11) # relinquish lock
+ movq %r10,_cygtls.stackptr(%r11) # restore
+ decl _cygtls.stacklock(%r11) # relinquish lock
xorl %r10d,%r10d
- movl %r10d,$tls::incyg(%r11) # we're not in cygwin anymore
+ movl %r10d,_cygtls.incyg(%r11) # we're not in cygwin anymore
movq 0x8(%rcx),%rbx
movq 0x10(%rcx),%rsp
movq 0x18(%rcx),%rbp
@@ -774,8 +772,8 @@ _setjmp:
fnstcw 48(%edi)
pushl %ebx
call stabilize_sig_stack
- movl $tls::stackptr(%ebx),%eax # save stack pointer contents
- decl $tls::stacklock(%ebx)
+ movl _cygtls.stackptr(%ebx),%eax # save stack pointer contents
+ decl _cygtls.stacklock(%ebx)
popl %ebx
movl %eax,52(%edi)
popl %edi
@@ -879,10 +877,10 @@ _longjmp:
1:
call stabilize_sig_stack
movl 52(%edi),%eax # get old signal stack
- movl %eax,$tls::stackptr(%ebx) # restore
- decl $tls::stacklock(%ebx) # relinquish lock
+ movl %eax,_cygtls.stackptr(%ebx) # restore
+ decl _cygtls.stacklock(%ebx) # relinquish lock
xorl %eax,%eax
- movl %eax,$tls::incyg(%ebx) # we're not in cygwin anymore
+ movl %eax,_cygtls.incyg(%ebx) # we're not in cygwin anymore
movl 12(%ebp),%eax
testl %eax,%eax
diff --git a/winsup/cygwin/gentls_offsets b/winsup/cygwin/gentls_offsets
index 8e9ce71..6892bd5 100755
--- a/winsup/cygwin/gentls_offsets
+++ b/winsup/cygwin/gentls_offsets
@@ -1,103 +1,83 @@
-#!/usr/bin/perl -s
-#
-# This file is part of Cygwin.
+#!/usr/bin/env bash
+#set -x
+input_file=$1
+output_file=$2
+
+# Preprocess cygtls.h and filter out only the member lines from
+# class _cygtls to generate an input file for the cross compiler
+# to generate the member offsets for tlsoffsets-$(target_cpu).h.
+${CXXCOMPILE} -E -P "${input_file}" 2> /dev/null | \
+gawk '
+ BEGIN {
+ # marker is used to split out the member lines from class _cygtls
+ marker=0;
+ # Prepare the input file for the subsequent compiler run.
+ # Prepend value of __CYGTLS_PADSIZE__ so we can compute the offsets
+ # up and down at the same time
+ print "#include \"winsup.h\"";
+ print "#include \"cygtls.h\"";
+ print "extern \"C\" const uint32_t __CYGTLS__start_offset = __CYGTLS_PADSIZE__;";
+ }
+ /^class _cygtls$/ {
+ # Ok, bump marker, next we are expecting a "public:" line
+ marker=1;
+ }
+ /^public:/ {
+ # We are only interested in the lines between the first (marker == 2)
+ # and the second (marker == 3) "public:" line in class _cygtls. These
+ # are where the members are defined.
+ if (marker > 0) ++marker;
+ if (marker > 2) exit;
+ }
+ {
+ if (marker == 2 && $1 != "public:") {
+ # Filter out function names
+ $0 = gensub (/\(\*(\w+)\)\s*\([^\)]*\)/, "\\1", "g");
+ # Filter out leading asterisk
+ $NF = gensub (/^\**(\w+)/, "\\1", "g", $NF);
+ # Filter out trailing array expression
+ $NF = gensub (/(\w+)\s*\[[^\]]*\]/, "\\1", "g", $NF);
+ $NF = gensub (/(\w+);/, "\\1", "g", $NF);
+ print "extern \"C\" const uint32_t __CYGTLS__" $NF " = offsetof (class _cygtls, " $NF ");";
+ }
+ }
+' | \
+# Now run the compiler to generate an assembler file.
+${CXXCOMPILE} -x c++ -g0 -S - -o - | \
+# The assembler file consists of lines like these:
#
-# This software is a copyrighted work licensed under the terms of the
-# Cygwin license. Please consult the file "CYGWIN_LICENSE" for
-# details.
+# __CYGTLS__foo
+# .long 42
+# .globl __CYGTLS__foo
+# .align 4
#
-my $tls = shift;
-my $tls_out = shift;
-my $tgt = shift;
-# FIXME? This method obviously requires a 64 bit OS to build tlsoffsets64.h
-# Another method which doesn't requires to run an executable would be to
-# generate assembler code accessing the various struct members and analyzing
-# it, but that's arguably a lot more effort.
-my $tgt_opt = $tgt eq 'x86_64' ? '-m64' : '-m32';
-open TLS, '<', $tls or die "$0: couldn't open tls file \"$tls\" - $!\n";
-my $struct = '';
-my @fields = ();
-my $def = '';
-$tls = join('', <TLS>);
-$tls =~ s/\A.*\n#pragma once\n//os;
-$tls =~ s/\n[^\n]*gentls_offsets[^\n]*\n(.+)\Z/$1/os;
-my $pre = $`;
-substr($tls, 0, length($pre)) = '';
-$pre .= "\n//*/";
-$tls =~ s%/\*\s*gentls_offsets.*?/\*\s*gentls_offsets\s*\*/%%ogs;
-foreach ($tls =~ /^.*\n/mg) {
- /^}|\s*(?:typedef|const)/ and do {
- $def .= $_ ;
- next;
- };
- $def .= $_ if $struct;
- if (!s/;.*$//) {
- if (!$struct && /^\s*(?:struct|class)\s*([a-z_0-9]+)/) {
- $def .= $_;
- $struct = $1
- }
- next;
- }
- s/(?:\[[^\]]*\]|struct|class)//;
- s/^\s+\S+\s+//;
- s/[\*\s()]+//g;
- for my $f (split(/,/)) {
- push(@fields, $f);
+# From this info, generate the tlsoffsets file.
+gawk '\
+ BEGIN {
+ varname=""
+ start_offset = 0
+ }
+ /^__CYGTLS__/ {
+ varname = gensub (/__CYGTLS__(\w+):/, "\\1", "g");
+ }
+ /\s*\.space\s*4/ {
+ if (length (varname) > 0) {
+ printf (".equ _cygtls.%s, %d\n", varname, -start_offset);
+ printf (".equ _cygtls.p%s, 0\n", varname);
+ varname = "";
}
-}
-close TLS;
-open TMP, '>', "/tmp/$$.cc" or die "$0: couldn't open temporary index file \"/tmp/$$.c\" - $!\n";
-print TMP <<EOF;
-#define __INSIDE_CYGWIN__
-#ifndef __x86_64__
-#define __attribute__(X)
-#endif
-#define __reg1
-#define __reg2
-#define __reg3
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <windows.h>
-$pre
-$def
-int
-main(int argc, char **argv)
-{
- $struct *foo;
-# define foo_beg ((char *) foo)
-# define offset(f) ((unsigned)((int) (((char *) &(foo->f)) - foo_beg) - __CYGTLS_PADSIZE__))
-# define poffset(f) ((unsigned)(((char *) &(foo->f)) - ((char *) foo)))
-EOF
- print TMP 'puts ("//;# autogenerated: Do not edit.\n");', "\n\n";
- print TMP "printf (\"//; \$tls::start_offset = -%d;\\n\", __CYGTLS_PADSIZE__);\n";
- for my $f (@fields) {
- print TMP ' printf ("//; $tls::', $f, ' = %d;\n", ', "offset($f));\n";
- print TMP ' printf ("//; $tls::p', $f, ' = %d;\n", ', "poffset($f));\n";
+ }
+ /\s*\.long\s+/ {
+ if (length (varname) > 0) {
+ if (varname == "start_offset") {
+ start_offset = $2;
+ printf (".equ _cygtls.%s, -%u\n", varname, start_offset);
+ } else {
+ value = $2;
+ printf (".equ _cygtls.%s, %d\n", varname, value - start_offset);
+ printf (".equ _cygtls.p%s, %d\n", varname, value);
+ }
+ varname = "";
}
- print TMP ' puts ("//; __DATA__\n");', "\n";
- for my $f (@fields) {
- print TMP ' printf ("#define tls_', $f, ' (%d)\n", ', "offset($f));\n";
- print TMP ' printf ("#define tls_p', $f, ' (%d)\n", ', "poffset($f));\n";
- }
-
- print TMP <<EOF;
-
- exit (0);
-}
-EOF
-close TMP;
-my @avoid_headers = qw'-D_XMMINTRIN_H_INCLUDED -D_ADXINTRIN_H_INCLUDED -D_EMMINTRIN_H_INCLUDED -D_X86INTRIN_H_INCLUDED';
-my @cmd = (@ARGV, @avoid_headers, '-o', "/tmp/$$-1.cc", '-E', "/tmp/$$.cc");
-
-system @cmd;
-system 'g++', "$tgt_opt", '-o', "/tmp/$$.a.out", "/tmp/$$-1.cc" and
-($? == 127 && system 'c++', "$tgt_opt", '-o', "/tmp/$$.a.out", "/tmp/$$-1.cc") and
-die "$0: couldn't generate executable for offset calculation \"/tmp/$$.a.out\" - $!\n";
-open TLS_OUT, '>', $tls_out or die "$0: couldn't open tls index file \"$tls_out\" - $!\n";
-open OFFS, '-|', "/tmp/$$.a.out" or die "$0: couldn't run \"/tmp/$$.a.out\" - $!\n";
-print TLS_OUT <OFFS>;
-close OFFS;
-close TLS_OUT;
-unlink "/tmp/$$.cc", "/tmp/$$-1.cc", "/tmp/$$-1.d", "/tmp/$$.a.out";
-exit(0);
+ }
+' > "${output_file}"
diff --git a/winsup/cygwin/tlsoffsets-x86_64.h b/winsup/cygwin/tlsoffsets-x86_64.h
deleted file mode 100644
index 9388cad..0000000
--- a/winsup/cygwin/tlsoffsets-x86_64.h
+++ /dev/null
@@ -1,125 +0,0 @@
-//;# autogenerated: Do not edit.
-
-//; $tls::start_offset = -12800;
-//; $tls::local_clib = -12800;
-//; $tls::plocal_clib = 0;
-//; $tls::__dontuse = -12800;
-//; $tls::p__dontuse = 0;
-//; $tls::locals = -10912;
-//; $tls::plocals = 1888;
-//; $tls::func = -8736;
-//; $tls::pfunc = 4064;
-//; $tls::saved_errno = -8728;
-//; $tls::psaved_errno = 4072;
-//; $tls::sa_flags = -8724;
-//; $tls::psa_flags = 4076;
-//; $tls::oldmask = -8720;
-//; $tls::poldmask = 4080;
-//; $tls::deltamask = -8712;
-//; $tls::pdeltamask = 4088;
-//; $tls::errno_addr = -8704;
-//; $tls::perrno_addr = 4096;
-//; $tls::sigmask = -8696;
-//; $tls::psigmask = 4104;
-//; $tls::sigwait_mask = -8688;
-//; $tls::psigwait_mask = 4112;
-//; $tls::altstack = -8680;
-//; $tls::paltstack = 4120;
-//; $tls::sigwait_info = -8656;
-//; $tls::psigwait_info = 4144;
-//; $tls::signal_arrived = -8648;
-//; $tls::psignal_arrived = 4152;
-//; $tls::will_wait_for_signal = -8640;
-//; $tls::pwill_wait_for_signal = 4160;
-//; $tls::__align = -8632;
-//; $tls::p__align = 4168;
-//; $tls::context = -8624;
-//; $tls::pcontext = 4176;
-//; $tls::thread_id = -7328;
-//; $tls::pthread_id = 5472;
-//; $tls::infodata = -7324;
-//; $tls::pinfodata = 5476;
-//; $tls::tid = -7176;
-//; $tls::ptid = 5624;
-//; $tls::_ctinfo = -7168;
-//; $tls::p_ctinfo = 5632;
-//; $tls::andreas = -7160;
-//; $tls::pandreas = 5640;
-//; $tls::wq = -7152;
-//; $tls::pwq = 5648;
-//; $tls::sig = -7104;
-//; $tls::psig = 5696;
-//; $tls::incyg = -7100;
-//; $tls::pincyg = 5700;
-//; $tls::spinning = -7096;
-//; $tls::pspinning = 5704;
-//; $tls::stacklock = -7092;
-//; $tls::pstacklock = 5708;
-//; $tls::stackptr = -7088;
-//; $tls::pstackptr = 5712;
-//; $tls::stack = -7080;
-//; $tls::pstack = 5720;
-//; $tls::initialized = -5032;
-//; $tls::pinitialized = 7768;
-//; __DATA__
-
-#define tls_local_clib (-12800)
-#define tls_plocal_clib (0)
-#define tls___dontuse (-12800)
-#define tls_p__dontuse (0)
-#define tls_locals (-10912)
-#define tls_plocals (1888)
-#define tls_func (-8736)
-#define tls_pfunc (4064)
-#define tls_saved_errno (-8728)
-#define tls_psaved_errno (4072)
-#define tls_sa_flags (-8724)
-#define tls_psa_flags (4076)
-#define tls_oldmask (-8720)
-#define tls_poldmask (4080)
-#define tls_deltamask (-8712)
-#define tls_pdeltamask (4088)
-#define tls_errno_addr (-8704)
-#define tls_perrno_addr (4096)
-#define tls_sigmask (-8696)
-#define tls_psigmask (4104)
-#define tls_sigwait_mask (-8688)
-#define tls_psigwait_mask (4112)
-#define tls_altstack (-8680)
-#define tls_paltstack (4120)
-#define tls_sigwait_info (-8656)
-#define tls_psigwait_info (4144)
-#define tls_signal_arrived (-8648)
-#define tls_psignal_arrived (4152)
-#define tls_will_wait_for_signal (-8640)
-#define tls_pwill_wait_for_signal (4160)
-#define tls___align (-8632)
-#define tls_p__align (4168)
-#define tls_context (-8624)
-#define tls_pcontext (4176)
-#define tls_thread_id (-7328)
-#define tls_pthread_id (5472)
-#define tls_infodata (-7324)
-#define tls_pinfodata (5476)
-#define tls_tid (-7176)
-#define tls_ptid (5624)
-#define tls__ctinfo (-7168)
-#define tls_p_ctinfo (5632)
-#define tls_andreas (-7160)
-#define tls_pandreas (5640)
-#define tls_wq (-7152)
-#define tls_pwq (5648)
-#define tls_sig (-7104)
-#define tls_psig (5696)
-#define tls_incyg (-7100)
-#define tls_pincyg (5700)
-#define tls_spinning (-7096)
-#define tls_pspinning (5704)
-#define tls_stacklock (-7092)
-#define tls_pstacklock (5708)
-#define tls_stackptr (-7088)
-#define tls_pstackptr (5712)
-#define tls_stack (-7080)
-#define tls_pstack (5720)
-#define tls_initialized (-5032)
-#define tls_pinitialized (7768)