Subject: [bug#74290] [PATCH v3 12/51] gnu: glibc/hurd: Add patches for the 64bit Hurd.

From: Janneke Nieuwenhuizen <[email-masked]>
Date: Tue, 19 Nov 2024 07:54:42 +0100

These patches fix:

  * Statically linked tar to hang/segfault upon issuing the "--mtime=@1"
  warning; this is also applicable for the 32bit Hurd using glibc-2.39!

See <https://lists.gnu.org/archive/html/bug-hurd/2024-11/msg00115.html>.

  * Shell replacement problems for the 64bit Hurd.

See <https://lists.debian.org/debian-hurd/2024/07/msg00063.html>.

* gnu/packages/patches/glibc-hurd-pthread_setcancelstate.patch,
gnu/packages/patches/glibc-hurd64-fault.patch,
gnu/packages/patches/glibc-hurd64-intr-msg-clobber.patch: New files.
* gnu/local.mk (dist_patch_DATA): Register them.
* gnu/packages/base.scm (glibc/hurd): Use them.

Change-Id: I9ee65983876cd22ad1dc01aabb41a34074631599
---
 gnu/local.mk                                  |  3 +
 gnu/packages/base.scm                         | 11 ++-
 .../glibc-hurd-pthread_setcancelstate.patch   | 92 +++++++++++++++++++
 gnu/packages/patches/glibc-hurd64-fault.patch | 32 +++++++
 .../glibc-hurd64-intr-msg-clobber.patch       | 62 +++++++++++++
 5 files changed, 199 insertions(+), 1 deletion(-)
 create mode 100644 gnu/packages/patches/glibc-hurd-pthread_setcancelstate.patch
 create mode 100644 gnu/packages/patches/glibc-hurd64-fault.patch
 create mode 100644 gnu/packages/patches/glibc-hurd64-intr-msg-clobber.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 9a775cc160..eb50df6e13 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1439,7 +1439,10 @@ dist_patch_DATA =						\
   %D%/packages/patches/glibc-hurd-getauxval.patch		\
   %D%/packages/patches/glibc-hurd-gettyent.patch		\
   %D%/packages/patches/glibc-hurd-mach-print.patch		\
+  %D%/packages/patches/glibc-hurd-pthread_setcancelstate.patch	\
   %D%/packages/patches/glibc-hurd-signal-sa-siginfo.patch	\
+  %D%/packages/patches/glibc-hurd64-fault.patch			\
+  %D%/packages/patches/glibc-hurd64-intr-msg-clobber.patch	\
   %D%/packages/patches/glibc-ldd-powerpc.patch			\
   %D%/packages/patches/glibc-ldd-x86_64.patch			\
   %D%/packages/patches/glibc-locales.patch			\
diff --git a/gnu/packages/base.scm b/gnu/packages/base.scm
index 83f8c0d9e9..bab1f258c6 100644
--- a/gnu/packages/base.scm
+++ b/gnu/packages/base.scm
@@ -1588,7 +1588,16 @@ (define-public which
 command.")
     (license gpl3+))) ; some files are under GPLv2+
 
-(define-public glibc/hurd glibc)
+(define-public glibc/hurd
+  (package/inherit glibc
+    (source
+     (origin
+       (inherit (package-source glibc))
+       (patches
+        (append (origin-patches (package-source glibc))
+                (search-patches "glibc-hurd-pthread_setcancelstate.patch"
+                                "glibc-hurd64-fault.patch"
+                                "glibc-hurd64-intr-msg-clobber.patch")))))))
 
 (define-public glibc/hurd-headers
   (package/inherit glibc/hurd
diff --git a/gnu/packages/patches/glibc-hurd-pthread_setcancelstate.patch b/gnu/packages/patches/glibc-hurd-pthread_setcancelstate.patch
new file mode 100644
index 0000000000..1d7c81b98e
--- /dev/null
+++ b/gnu/packages/patches/glibc-hurd-pthread_setcancelstate.patch
@@ -0,0 +1,92 @@
+Upstream-status: Taken from <https://salsa.debian.org/glibc-team/glibc/-/blob/25a0a47767fe7dc5151eb36afaade17218728efe/debian/patches/hurd-i386/local-static_pthread_setcancelstate.diff>.
+
+This is needed for the 64bit Hurd statically linked tar non to hang when
+issuing a warning.
+
+since the move of libpthread functions to libc, glibc dropped the use
+of __libc_ptf_call. But htl hasn't made the move yet, so we have to use
+__libc_ptf_call there for now.
+
+Index: glibc-2.36/misc/error.c
+===================================================================
+--- glibc-2.36.orig/misc/error.c
++++ glibc-2.36/misc/error.c
+@@ -240,7 +240,8 @@ __error_internal (int status, int errnum
+   /* We do not want this call to be cut short by a thread
+      cancellation.  Therefore disable cancellation for now.  */
+   int state = PTHREAD_CANCEL_ENABLE;
+-  __pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &state);
++  __libc_ptf_call (__pthread_setcancelstate,
++		   (PTHREAD_CANCEL_DISABLE, &state), 0);
+ #endif
+ 
+   flush_stdout ();
+@@ -262,7 +263,7 @@ __error_internal (int status, int errnum
+ 
+ #ifdef _LIBC
+   _IO_funlockfile (stderr);
+-  __pthread_setcancelstate (state, NULL);
++  __libc_ptf_call (__pthread_setcancelstate, (state, NULL), 0);
+ #endif
+ }
+ 
+@@ -306,7 +307,9 @@ __error_at_line_internal (int status, in
+   /* We do not want this call to be cut short by a thread
+      cancellation.  Therefore disable cancellation for now.  */
+   int state = PTHREAD_CANCEL_ENABLE;
+-  __pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &state);
++  __libc_ptf_call (__pthread_setcancelstate,
++		   (PTHREAD_CANCEL_DISABLE, &state),
++		   0);
+ #endif
+ 
+   flush_stdout ();
+@@ -336,7 +339,7 @@ __error_at_line_internal (int status, in
+ 
+ #ifdef _LIBC
+   _IO_funlockfile (stderr);
+-  __pthread_setcancelstate (state, NULL);
++  __libc_ptf_call (__pthread_setcancelstate, (state, NULL), 0);
+ #endif
+ }
+ 
+Index: glibc-2.36/libio/iopopen.c
+===================================================================
+--- glibc-2.36.orig/libio/iopopen.c
++++ glibc-2.36/libio/iopopen.c
+@@ -281,9 +281,10 @@ _IO_new_proc_close (FILE *fp)
+   do
+     {
+       int state;
+-      __pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &state);
++      __libc_ptf_call (__pthread_setcancelstate,
++		       (PTHREAD_CANCEL_DISABLE, &state), 0);
+       wait_pid = __waitpid (((_IO_proc_file *) fp)->pid, &wstatus, 0);
+-      __pthread_setcancelstate (state, NULL);
++      __libc_ptf_call (__pthread_setcancelstate, (state, NULL), 0);
+     }
+   while (wait_pid == -1 && errno == EINTR);
+   if (wait_pid == -1)
+Index: glibc-2.36/stdlib/fmtmsg.c
+===================================================================
+--- glibc-2.36.orig/stdlib/fmtmsg.c
++++ glibc-2.36/stdlib/fmtmsg.c
+@@ -124,7 +124,8 @@ fmtmsg (long int classification, const c
+   /* We do not want this call to be cut short by a thread
+      cancellation.  Therefore disable cancellation for now.  */
+   int state = PTHREAD_CANCEL_ENABLE;
+-  __pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &state);
++  __libc_ptf_call (__pthread_setcancelstate,
++		   (PTHREAD_CANCEL_DISABLE, &state), 0);
+ 
+   __libc_lock_lock (lock);
+ 
+@@ -193,7 +194,7 @@ fmtmsg (long int classification, const c
+ 
+   __libc_lock_unlock (lock);
+ 
+-  __pthread_setcancelstate (state, NULL);
++  __libc_ptf_call (__pthread_setcancelstate, (state, NULL), 0);
+ 
+   return result;
+ }
diff --git a/gnu/packages/patches/glibc-hurd64-fault.patch b/gnu/packages/patches/glibc-hurd64-fault.patch
new file mode 100644
index 0000000000..24980e8c2a
--- /dev/null
+++ b/gnu/packages/patches/glibc-hurd64-fault.patch
@@ -0,0 +1,32 @@
+Upstream-status: Taken from: <https://salsa.debian.org/glibc-team/glibc/-/blob/c36c87acb1a35d6e06db6cef1e28cf2f405e1a9e/debian/patches/hurd-i386/git-fault-64bit.diff>.
+
+See <https://lists.gnu.org/archive/html/bug-hurd/2024-11/msg00115.html>.
+
+commit 11ad033e1c09c8b8e7bbaa72420f41ab8bcf0f63
+Author: Flavio Cruz <[email-masked]>
+Date:   Tue Jul 30 00:51:20 2024 -0400
+
+    x86_64 hurd: ensure we have a large enough buffer to receive exception_raise requests.
+    
+    Message-ID: <gtxd6s4s7fi7hdrlb7zayq3akij7x6jqawwq3zfl3v4nqspulo@euucuzeonrl6>
+
+diff --git a/hurd/hurdfault.c b/hurd/hurdfault.c
+index 5110c6030f..1fe973f54d 100644
+--- a/hurd/hurdfault.c
++++ b/hurd/hurdfault.c
+@@ -121,7 +121,14 @@ faulted (void)
+   struct
+     {
+       mach_msg_header_t head;
+-      char buf[64];
++        /* This is the size of the exception_raise request
++         * including mach_msg_header_t.
++         * See generated code in faultexc_server.c.  */
++#ifdef __LP64__
++        char buf[112];
++#else
++        char buf[64];
++#endif
+     } request;
+   mig_reply_header_t reply;
+   extern int _hurdsig_fault_exc_server (mach_msg_header_t *,
diff --git a/gnu/packages/patches/glibc-hurd64-intr-msg-clobber.patch b/gnu/packages/patches/glibc-hurd64-intr-msg-clobber.patch
new file mode 100644
index 0000000000..600f89a711
--- /dev/null
+++ b/gnu/packages/patches/glibc-hurd64-intr-msg-clobber.patch
@@ -0,0 +1,62 @@
+Upstream-status: Taken from <https://salsa.debian.org/glibc-team/glibc/-/blob/c36c87acb1a35d6e06db6cef1e28cf2f405e1a9e/debian/patches/hurd-i386/git-intr-msg-clobber.diff>.
+
+See <https://lists.gnu.org/archive/html/bug-hurd/2024-11/msg00115.html>,
+and <https://lists.debian.org/debian-hurd/2024/07/msg00063.html>.
+
+Commited for 2.40
+
+commit c8b4ce0b368115714bd4cce131e1683759471099
+Author: Samuel Thibault <[email-masked]>
+Date:   Sat Jul 13 17:00:55 2024 +0200
+
+    hurd: Fix restoring message to be retried
+    
+    save_data stores the start of the original message to be retried,
+    overwritten by the EINTR reply. In 64b builds the overwrite is however
+    rounded up to the 64b pointer size, so we have to save more than just
+    the 32b err.
+    
+    Thanks a lot to Luca Dariz for the investigation!
+
+diff --git a/hurd/intr-msg.c b/hurd/intr-msg.c
+index 2c2e7dc463..424c1fc700 100644
+--- a/hurd/intr-msg.c
++++ b/hurd/intr-msg.c
+@@ -42,7 +42,10 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
+   struct clobber
+   {
+     mach_msg_type_t type;
+-    error_t err;
++    union {
++      error_t err;
++      uintptr_t align;
++    };
+   };
+   union msg
+   {
+
+Taken from: <https://salsa.debian.org/glibc-team/glibc/-/blob/027f94215a633cbf53794d4b48675fde36706e35/debian/patches/hurd-i386/local-intr-msg-clobber.diff>
+
+Force putting save_data on the stack rather than in SSE register
+
+The signal management does not yet properly save SSE state, so that save_data
+would get overwritten by signal handlers, notably leading to `` shell
+replacement getting empty content because then the io_read RPC retry gets an
+MIG_BAD_ARGUMENTS error.
+
+XXX: This is only temporary to fix the common shll replacement issue, and is
+waiting for proper SSE state restoration.
+
+Index: glibc-2.38/hurd/intr-msg.c
+===================================================================
+--- glibc-2.38.orig/hurd/intr-msg.c
++++ glibc-2.38/hurd/intr-msg.c
+@@ -79,7 +79,7 @@ _hurd_intr_rpc_mach_msg (mach_msg_header
+   mach_msg_bits_t msgh_bits;
+   mach_port_t remote_port;
+   mach_msg_id_t msgid;
+-  struct clobber save_data;
++  volatile struct clobber save_data;
+ 
+   if ((option & (MACH_SEND_MSG|MACH_RCV_MSG)) != (MACH_SEND_MSG|MACH_RCV_MSG)
+       || _hurd_msgport_thread == MACH_PORT_NULL)
-- 
2.46.0