public inbox for cygwin-cvs@sourceware.org
help / color / mirror / Atom feed
From: Corinna Vinschen <corinna@sourceware.org>
To: cygwin-cvs@sourceware.org
Subject: [newlib-cygwin] Cygwin: revamp TLS offsets computation
Date: Fri, 13 May 2022 12:38:32 +0000 (GMT)	[thread overview]
Message-ID: <20220513123832.9E764395B066@sourceware.org> (raw)

https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=0597c84b9bdbdab806fb4674565f173d59475da7

commit 0597c84b9bdbdab806fb4674565f173d59475da7
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Wed Feb 2 17:27:34 2022 +0100

    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>

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
 
 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 5fd87c6e8..fe17a5b1b 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 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;
 
-/* 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 431ec67d3..779cdcfd0 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 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=$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 f9d4987c2..000000000
--- 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 = -11488;
-//; $tls::plocals = 1312;
-//; $tls::func = -9312;
-//; $tls::pfunc = 3488;
-//; $tls::saved_errno = -9304;
-//; $tls::psaved_errno = 3496;
-//; $tls::sa_flags = -9300;
-//; $tls::psa_flags = 3500;
-//; $tls::oldmask = -9296;
-//; $tls::poldmask = 3504;
-//; $tls::deltamask = -9288;
-//; $tls::pdeltamask = 3512;
-//; $tls::errno_addr = -9280;
-//; $tls::perrno_addr = 3520;
-//; $tls::sigmask = -9272;
-//; $tls::psigmask = 3528;
-//; $tls::sigwait_mask = -9264;
-//; $tls::psigwait_mask = 3536;
-//; $tls::altstack = -9256;
-//; $tls::paltstack = 3544;
-//; $tls::sigwait_info = -9232;
-//; $tls::psigwait_info = 3568;
-//; $tls::signal_arrived = -9224;
-//; $tls::psignal_arrived = 3576;
-//; $tls::will_wait_for_signal = -9216;
-//; $tls::pwill_wait_for_signal = 3584;
-//; $tls::__align = -9208;
-//; $tls::p__align = 3592;
-//; $tls::context = -9200;
-//; $tls::pcontext = 3600;
-//; $tls::thread_id = -7904;
-//; $tls::pthread_id = 4896;
-//; $tls::infodata = -7900;
-//; $tls::pinfodata = 4900;
-//; $tls::tid = -7752;
-//; $tls::ptid = 5048;
-//; $tls::_ctinfo = -7744;
-//; $tls::p_ctinfo = 5056;
-//; $tls::andreas = -7736;
-//; $tls::pandreas = 5064;
-//; $tls::wq = -7728;
-//; $tls::pwq = 5072;
-//; $tls::sig = -7680;
-//; $tls::psig = 5120;
-//; $tls::incyg = -7676;
-//; $tls::pincyg = 5124;
-//; $tls::spinning = -7672;
-//; $tls::pspinning = 5128;
-//; $tls::stacklock = -7668;
-//; $tls::pstacklock = 5132;
-//; $tls::stackptr = -7664;
-//; $tls::pstackptr = 5136;
-//; $tls::stack = -7656;
-//; $tls::pstack = 5144;
-//; $tls::initialized = -5608;
-//; $tls::pinitialized = 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)


                 reply	other threads:[~2022-05-13 12:38 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220513123832.9E764395B066@sourceware.org \
    --to=corinna@sourceware.org \
    --cc=cygwin-cvs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).