This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
mingw 32-bit: realign the stack in our callbacks
authorTony Cook <tony@develop-help.com>
Thu, 3 Aug 2023 03:33:28 +0000 (13:33 +1000)
committerTony Cook <tony@develop-help.com>
Mon, 7 Aug 2023 00:08:47 +0000 (10:08 +1000)
A default 32-bit mingw build assumes the stack is 16 byte aligned,
which appears to be a problem with gcc.

With quadmath enabled, libgcc includes instructions that require
16-byte alignment and access relative to the stack pointer, and
when the stack isn't aligned, results in a crash.

To prevent that add the force_align_arg_pointer attribute to our
callbacks for 32-bit gcc on Windows.

dist/threads/lib/threads.pm
dist/threads/threads.xs
mg.c
perl.h
win32/perlhost.h

index 06485b3..2c02ba3 100644 (file)
@@ -5,7 +5,7 @@ use 5.008;
 use strict;
 use warnings;
 
-our $VERSION = '2.37';      # remember to update version in POD!
+our $VERSION = '2.38';      # remember to update version in POD!
 my $XS_VERSION = $VERSION;
 $VERSION = eval $VERSION;
 
@@ -134,7 +134,7 @@ threads - Perl interpreter-based threads
 
 =head1 VERSION
 
-This document describes threads version 2.37
+This document describes threads version 2.38
 
 =head1 WARNING
 
index 92c5fd8..fdcdc29 100644 (file)
@@ -535,11 +535,11 @@ S_jmpenv_run(pTHX_ int action, ithread *thread,
     return jmp_rc;
 }
 
-
 /* Starts executing the thread.
  * Passed as the C level function to run in the new thread.
  */
 #ifdef WIN32
+PERL_STACK_REALIGN
 STATIC THREAD_RET_TYPE
 S_ithread_run(LPVOID arg)
 #else
diff --git a/mg.c b/mg.c
index 899cc4a..4b6d4ab 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -1526,6 +1526,7 @@ Perl_magic_clearsig(pTHX_ SV *sv, MAGIC *mg)
 }
 
 
+PERL_STACK_REALIGN
 #ifdef PERL_USE_3ARG_SIGHANDLER
 Signal_t
 Perl_csighandler(int sig, Siginfo_t *sip, void *uap)
diff --git a/perl.h b/perl.h
index a96537d..20d9f33 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -9099,6 +9099,33 @@ END_EXTERN_C
 
 #define PERL_PARSE_ERROR_COUNT(f)     (f)
 
+
+/* Work around
+
+  https://github.com/Perl/perl5/issues/21313
+
+  Where gcc when generating code for 32-bit windows assumes the stack
+  is 16 byte aligned, where the system doesn't guarantee that.
+
+  The code generated by gcc itself does maintain 16 byte alignment,
+  but callbacks from the CRT or Windows APIs don't, so calls to
+  code that is generated to SSE instructions (like the quadmath code
+  by default), crashes when called from a callback.
+
+  Since other code other than quadmath might use SSE instructions,
+  also enable this outside of quadmath builds.
+
+  This change is a little risky: if an XS module uses callbacks
+  and those callbacks may also produce alignment errors, if that
+  becomes a problem we'll need to use the nuclear option: building
+  32-bit perl with -mstackrealign.
+*/
+#if defined(WIN32) && !defined(WIN64) && defined(__GNUC__)
+#  define PERL_STACK_REALIGN __attribute__((force_align_arg_pointer))
+#else
+#  define PERL_STACK_REALIGN
+#endif
+
 /*
 
    (KEEP THIS LAST IN perl.h!)
index e6ef46f..9a2e24c 100644 (file)
@@ -1692,6 +1692,7 @@ PerlProcGetTimeOfDay(struct IPerlProc* piPerl, struct timeval *t, void *z)
 }
 
 #ifdef USE_ITHREADS
+PERL_STACK_REALIGN
 static THREAD_RET_TYPE
 win32_start_child(LPVOID arg)
 {