diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2022-02-02 17:27:34 +0100 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2022-05-12 22:00:25 +0200 |
commit | ccf1638e8ec8880f5b2282084a1e34bbb61f9051 (patch) | |
tree | 7a89407321650e562cc4d661808724661eeb6f96 /winsup | |
parent | b5dcb1e5e39f16a8aa207f48f2bd889348110d25 (diff) | |
download | newlib-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.ac | 2 | ||||
-rw-r--r-- | winsup/cygwin/Makefile.am | 14 | ||||
-rw-r--r-- | winsup/cygwin/cygtls.h | 28 | ||||
-rwxr-xr-x | winsup/cygwin/gendef | 154 | ||||
-rwxr-xr-x | winsup/cygwin/gentls_offsets | 178 | ||||
-rw-r--r-- | winsup/cygwin/tlsoffsets-x86_64.h | 125 |
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) |