From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2155) id 9E764395B066; Fri, 13 May 2022 12:38:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9E764395B066 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Corinna Vinschen To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin] Cygwin: revamp TLS offsets computation X-Act-Checkin: newlib-cygwin X-Git-Author: Corinna Vinschen X-Git-Refname: refs/heads/master X-Git-Oldrev: c0d5bb262dcd72b0256ed27460ebd0fd7a7d582d X-Git-Newrev: 0597c84b9bdbdab806fb4674565f173d59475da7 Message-Id: <20220513123832.9E764395B066@sourceware.org> Date: Fri, 13 May 2022 12:38:32 +0000 (GMT) X-BeenThere: cygwin-cvs@cygwin.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Cygwin core component git logs List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 13 May 2022 12:38:32 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3D0597c84b9bd= bdab806fb4674565f173d59475da7 commit 0597c84b9bdbdab806fb4674565f173d59475da7 Author: Corinna Vinschen Date: Wed Feb 2 17:27:34 2022 +0100 Cygwin: revamp TLS offsets computation =20 - convert gentls_offsets to a shell script, only running the target compiler and gawk. =20 - 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. =20 - 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. =20 - 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. =20 Signed-off-by: Corinna Vinschen Diff: --- winsup/configure.ac | 2 - winsup/cygwin/Makefile.am | 14 +-- winsup/cygwin/cygtls.h | 28 ++---- winsup/cygwin/gendef | 154 ++++++++++++++++----------------- winsup/cygwin/gentls_offsets | 178 +++++++++++++++++-----------------= ---- 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 5d83c230a..634493e59 100644 --- a/winsup/configure.ac +++ b/winsup/configure.ac @@ -67,7 +67,6 @@ esac =20 DLL_ENTRY=3D"dll_entry" DIN_FILE=3D"${target_cpu}.din" -TLSOFFSETS_H=3D"tlsoffsets-${target_cpu}.h" =20 case "$target_cpu" in x86_64) ;; @@ -76,7 +75,6 @@ esac =20 AC_SUBST(DLL_ENTRY) AC_SUBST(DIN_FILE) -AC_SUBST(TLSOFFSETS_H) =20 AM_CONDITIONAL(TARGET_X86_64, [test $target_cpu =3D "x86_64"]) =20 diff --git a/winsup/cygwin/Makefile.am b/winsup/cygwin/Makefile.am index 5fd87c6e8..fe17a5b1b 100644 --- a/winsup/cygwin/Makefile.am +++ b/winsup/cygwin/Makefile.am @@ -45,7 +45,6 @@ DBG_DLL_NAME=3Dcygwin1.dbg NEW_DLL_NAME=3Dnew-cygwin1.dll DIN_FILE=3D@DIN_FILE@ DEF_FILE=3Dcygwin.def -TLSOFFSETS_H=3D@TLSOFFSETS_H@ LIB_NAME=3Dlibcygwin.a TEST_LIB_NAME=3Dlibcygwin0.a =20 @@ -386,8 +385,8 @@ localtime.patched.c: tzcode/localtime.c tzcode/localtim= e.c.patch $(srcdir)/devices.cc: gendevices devices.in devices.h $(wordlist 1,2,$^) $@ =20 -$(srcdir)/$(TLSOFFSETS_H): gentls_offsets cygtls.h - $^ $@ $(target_cpu) $(CC) $(AM_CFLAGS) -c || rm $@ +tlsoffsets: gentls_offsets cygtls.h + $(AM_V_GEN)CXXCOMPILE=3D"$(CXXCOMPILE)" $^ $@ =20 BUILT_SOURCES =3D \ child_info_magic.h \ @@ -609,10 +608,10 @@ $(NEW_DLL_NAME): $(PRE_DLL_NAME) $(DBG_DLL_NAME) # cygwin import library toolopts=3D--cpu=3D@target_cpu@ --ar=3D@AR@ --as=3D@AS@ --nm=3D@NM@ --objc= opy=3D@OBJCOPY@ =20 -$(DEF_FILE): gendef $(srcdir)/$(TLSOFFSETS_H) $(DIN_FILE) common.din - $(AM_V_GEN)$(srcdir)/gendef --cpu=3D@target_cpu@ --output-def=3D$(DEF_FIL= E) --tlsoffsets=3D$(srcdir)/$(TLSOFFSETS_H) $(srcdir)/$(DIN_FILE) $(srcdir)= /common.din +$(DEF_FILE): gendef $(DIN_FILE) common.din + $(AM_V_GEN)$(srcdir)/gendef --cpu=3D@target_cpu@ --output-def=3D$(DEF_FIL= E) $(srcdir)/$(DIN_FILE) $(srcdir)/common.din =20 -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 =20 maintainer-clean-local: - -rm -f $(srcdir)/$(TLSOFFSETS_H) $(srcdir)/devices.cc + -rm -f $(srcdir)/devices.cc =20 # # install diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index 7ee61654e..c4702e88a 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -152,33 +152,22 @@ typedef struct struct_waitq HANDLE thread_ev; } waitq; =20 -/* Changes to the below structure may require acompanying changes to the v= ery - simple parser in the perl script 'gentls_offsets' (<<-- start parsing h= ere). - The union in this structure is used to force alignment between the vers= ion - of the compiler used to generate tlsoffsets.h and the cygwin cross comp= iler. -*/ - -/*gentls_offsets*/ +/* Changes to the below structure may require acompanying changes to the + gawk parser in the shell script 'gentls_offsets' */ =20 extern "C" int __sjfault (jmp_buf); extern "C" int __ljfault (jmp_buf, int); =20 -/*gentls_offsets*/ - typedef uintptr_t __tlsstack_t; =20 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_offse= ts. */ + /* 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_offset= s*/; + 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; =20 - /*gentls_offsets*/ +public: /* Do NOT remove this public: line, it's a marker for gentls_offse= ts. */ 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) =20 -/*gentls_offsets*/ - #include "cygerrno.h" #include "ntdll.h" =20 diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef index 431ec67d3..779cdcfd0 100755 --- a/winsup/cygwin/gendef +++ b/winsup/cygwin/gendef @@ -14,16 +14,13 @@ sub cleanup(@); =20 my $cpu; my $output_def; -my $tls_offsets; -GetOptions('cpu=3Ds'=3D>\$cpu, 'output-def=3Ds'=3D>\$output_def, 'tlsoffse= ts=3Ds'=3D>\$tls_offsets); +GetOptions('cpu=3Ds'=3D>\$cpu, 'output-def=3Ds'=3D>\$output_def); =20 $main::first =3D 0; -if (!defined($cpu) || !defined($output_def) || !defined($tls_offsets)) { +if (!defined($cpu) || !defined($output_def)) { die "$0: missing required option\n"; } =20 -require $tls_offsets; - my $is64bit =3D $cpu eq 'x86_64'; my $sym_prefix =3D $is64bit ? '' : '_'; =20 @@ -125,16 +122,17 @@ EOF if (!$main::first++) { if ($is64bit) { $res =3D < 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 =20 @@ -248,29 +246,29 @@ sigdelayed: .seh_endprologue =20 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 =20 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 =20 @@ -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 =20 @@ -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 =20 @@ -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 =20 - 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 =20 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 =20 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 =20 .global __ZN7_cygtls6lockedEv __ZN7_cygtls6lockedEv: - movl $tls::pstacklock(%eax),%eax + movl _cygtls.pstacklock(%eax),%eax ret =20 .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 =20 movl 12(%ebp),%eax testl %eax,%eax diff --git a/winsup/cygwin/gentls_offsets b/winsup/cygwin/gentls_offsets index 8e9ce7100..6892bd528 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=3D$1 +output_file=3D$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=3D0; + # 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 =3D __CYGTLS= _PADSIZE__;"; + } + /^class _cygtls$/ { + # Ok, bump marker, next we are expecting a "public:" line + marker=3D1; + } + /^public:/ { + # We are only interested in the lines between the first (marker =3D=3D= 2) + # and the second (marker =3D=3D 3) "public:" line in class _cygtls. T= hese + # are where the members are defined. + if (marker > 0) ++marker; + if (marker > 2) exit; + } + { + if (marker =3D=3D 2 && $1 !=3D "public:") { + # Filter out function names + $0 =3D gensub (/\(\*(\w+)\)\s*\([^\)]*\)/, "\\1", "g"); + # Filter out leading asterisk + $NF =3D gensub (/^\**(\w+)/, "\\1", "g", $NF); + # Filter out trailing array expression + $NF =3D gensub (/(\w+)\s*\[[^\]]*\]/, "\\1", "g", $NF); + $NF =3D gensub (/(\w+);/, "\\1", "g", $NF); + print "extern \"C\" const uint32_t __CYGTLS__" $NF " =3D offsetof (c= lass _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 =3D shift; -my $tls_out =3D shift; -my $tgt =3D 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 analyzi= ng -# it, but that's arguably a lot more effort. -my $tgt_opt =3D $tgt eq 'x86_64' ? '-m64' : '-m32'; -open TLS, '<', $tls or die "$0: couldn't open tls file \"$tls\" - $!\n"; -my $struct =3D ''; -my @fields =3D (); -my $def =3D ''; -$tls =3D join('', ); -$tls =3D~ s/\A.*\n#pragma once\n//os; -$tls =3D~ s/\n[^\n]*gentls_offsets[^\n]*\n(.+)\Z/$1/os; -my $pre =3D $`; -substr($tls, 0, length($pre)) =3D ''; -$pre .=3D "\n//*/"; -$tls =3D~ s%/\*\s*gentls_offsets.*?/\*\s*gentls_offsets\s*\*/%%ogs; -foreach ($tls =3D~ /^.*\n/mg) { - /^}|\s*(?:typedef|const)/ and do { - $def .=3D $_ ; - next; - }; - $def .=3D $_ if $struct; - if (!s/;.*$//) { - if (!$struct && /^\s*(?:struct|class)\s*([a-z_0-9]+)/) { - $def .=3D $_; - $struct =3D $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=3D"" + start_offset =3D 0 + } + /^__CYGTLS__/ { + varname =3D 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 =3D ""; } -} -close TLS; -open TMP, '>', "/tmp/$$.cc" or die "$0: couldn't open temporary index file= \"/tmp/$$.c\" - $!\n"; -print TMP < -#include -#include -#include -$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 =3D -%d;\\n\", __CYGTLS_P= ADSIZE__);\n"; - for my $f (@fields) { - print TMP ' printf ("//; $tls::', $f, ' =3D %d;\n", ', "offset($f));\n"; - print TMP ' printf ("//; $tls::p', $f, ' =3D %d;\n", ', "poffset($f));\n= "; + } + /\s*\.long\s+/ { + if (length (varname) > 0) { + if (varname =3D=3D "start_offset") { + start_offset =3D $2; + printf (".equ _cygtls.%s, -%u\n", varname, start_offset); + } else { + value =3D $2; + printf (".equ _cygtls.%s, %d\n", varname, value - start_offset); + printf (".equ _cygtls.p%s, %d\n", varname, value); + } + varname =3D ""; } - 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 <', $tls_out or die "$0: couldn't open tls index file \"$tl= s_out\" - $!\n"; -open OFFS, '-|', "/tmp/$$.a.out" or die "$0: couldn't run \"/tmp/$$.a.out\= " - $!\n"; -print TLS_OUT ; -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-x= 86_64.h deleted file mode 100644 index f9d4987c2..000000000 --- a/winsup/cygwin/tlsoffsets-x86_64.h +++ /dev/null @@ -1,125 +0,0 @@ -//;# autogenerated: Do not edit. - -//; $tls::start_offset =3D -12800; -//; $tls::local_clib =3D -12800; -//; $tls::plocal_clib =3D 0; -//; $tls::__dontuse =3D -12800; -//; $tls::p__dontuse =3D 0; -//; $tls::locals =3D -11488; -//; $tls::plocals =3D 1312; -//; $tls::func =3D -9312; -//; $tls::pfunc =3D 3488; -//; $tls::saved_errno =3D -9304; -//; $tls::psaved_errno =3D 3496; -//; $tls::sa_flags =3D -9300; -//; $tls::psa_flags =3D 3500; -//; $tls::oldmask =3D -9296; -//; $tls::poldmask =3D 3504; -//; $tls::deltamask =3D -9288; -//; $tls::pdeltamask =3D 3512; -//; $tls::errno_addr =3D -9280; -//; $tls::perrno_addr =3D 3520; -//; $tls::sigmask =3D -9272; -//; $tls::psigmask =3D 3528; -//; $tls::sigwait_mask =3D -9264; -//; $tls::psigwait_mask =3D 3536; -//; $tls::altstack =3D -9256; -//; $tls::paltstack =3D 3544; -//; $tls::sigwait_info =3D -9232; -//; $tls::psigwait_info =3D 3568; -//; $tls::signal_arrived =3D -9224; -//; $tls::psignal_arrived =3D 3576; -//; $tls::will_wait_for_signal =3D -9216; -//; $tls::pwill_wait_for_signal =3D 3584; -//; $tls::__align =3D -9208; -//; $tls::p__align =3D 3592; -//; $tls::context =3D -9200; -//; $tls::pcontext =3D 3600; -//; $tls::thread_id =3D -7904; -//; $tls::pthread_id =3D 4896; -//; $tls::infodata =3D -7900; -//; $tls::pinfodata =3D 4900; -//; $tls::tid =3D -7752; -//; $tls::ptid =3D 5048; -//; $tls::_ctinfo =3D -7744; -//; $tls::p_ctinfo =3D 5056; -//; $tls::andreas =3D -7736; -//; $tls::pandreas =3D 5064; -//; $tls::wq =3D -7728; -//; $tls::pwq =3D 5072; -//; $tls::sig =3D -7680; -//; $tls::psig =3D 5120; -//; $tls::incyg =3D -7676; -//; $tls::pincyg =3D 5124; -//; $tls::spinning =3D -7672; -//; $tls::pspinning =3D 5128; -//; $tls::stacklock =3D -7668; -//; $tls::pstacklock =3D 5132; -//; $tls::stackptr =3D -7664; -//; $tls::pstackptr =3D 5136; -//; $tls::stack =3D -7656; -//; $tls::pstack =3D 5144; -//; $tls::initialized =3D -5608; -//; $tls::pinitialized =3D 7192; -//; __DATA__ - -#define tls_local_clib (-12800) -#define tls_plocal_clib (0) -#define tls___dontuse (-12800) -#define tls_p__dontuse (0) -#define tls_locals (-11488) -#define tls_plocals (1312) -#define tls_func (-9312) -#define tls_pfunc (3488) -#define tls_saved_errno (-9304) -#define tls_psaved_errno (3496) -#define tls_sa_flags (-9300) -#define tls_psa_flags (3500) -#define tls_oldmask (-9296) -#define tls_poldmask (3504) -#define tls_deltamask (-9288) -#define tls_pdeltamask (3512) -#define tls_errno_addr (-9280) -#define tls_perrno_addr (3520) -#define tls_sigmask (-9272) -#define tls_psigmask (3528) -#define tls_sigwait_mask (-9264) -#define tls_psigwait_mask (3536) -#define tls_altstack (-9256) -#define tls_paltstack (3544) -#define tls_sigwait_info (-9232) -#define tls_psigwait_info (3568) -#define tls_signal_arrived (-9224) -#define tls_psignal_arrived (3576) -#define tls_will_wait_for_signal (-9216) -#define tls_pwill_wait_for_signal (3584) -#define tls___align (-9208) -#define tls_p__align (3592) -#define tls_context (-9200) -#define tls_pcontext (3600) -#define tls_thread_id (-7904) -#define tls_pthread_id (4896) -#define tls_infodata (-7900) -#define tls_pinfodata (4900) -#define tls_tid (-7752) -#define tls_ptid (5048) -#define tls__ctinfo (-7744) -#define tls_p_ctinfo (5056) -#define tls_andreas (-7736) -#define tls_pandreas (5064) -#define tls_wq (-7728) -#define tls_pwq (5072) -#define tls_sig (-7680) -#define tls_psig (5120) -#define tls_incyg (-7676) -#define tls_pincyg (5124) -#define tls_spinning (-7672) -#define tls_pspinning (5128) -#define tls_stacklock (-7668) -#define tls_pstacklock (5132) -#define tls_stackptr (-7664) -#define tls_pstackptr (5136) -#define tls_stack (-7656) -#define tls_pstack (5144) -#define tls_initialized (-5608) -#define tls_pinitialized (7192)