[PATCH 3/3] Mark various cold functions as __COLD

2023-04-29 Thread Sergey Bugaev
GCC docs explicitly list perror () as a good candidate for using
__attribute__ ((cold)). So apply __COLD to perror () and similar
functions.

Signed-off-by: Sergey Bugaev 
---
 include/error.h |  4 ++--
 libio/stdio.h   |  2 +-
 misc/err.h  | 12 ++--
 misc/error.h|  4 ++--
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/include/error.h b/include/error.h
index 9e96262f..4db67cba 100644
--- a/include/error.h
+++ b/include/error.h
@@ -5,11 +5,11 @@
 
 void
 __error_internal (int status, int errnum, const char *message,
- va_list args, unsigned int mode_flags);
+ va_list args, unsigned int mode_flags) __COLD;
 
 void
 __error_at_line_internal (int status, int errnum, const char *file_name,
  unsigned int line_number, const char *message,
- va_list args, unsigned int mode_flags);
+ va_list args, unsigned int mode_flags) __COLD;
 
 #endif
diff --git a/libio/stdio.h b/libio/stdio.h
index 45ddafdf..2387590d 100644
--- a/libio/stdio.h
+++ b/libio/stdio.h
@@ -859,7 +859,7 @@ extern int ferror_unlocked (FILE *__stream) __THROW __wur;
 
This function is a possible cancellation point and therefore not
marked with __THROW.  */
-extern void perror (const char *__s);
+extern void perror (const char *__s) __COLD;
 
 
 #ifdef __USE_POSIX
diff --git a/misc/err.h b/misc/err.h
index 0c752465..43df3a57 100644
--- a/misc/err.h
+++ b/misc/err.h
@@ -32,9 +32,9 @@ __BEGIN_DECLS
 /* Print "program: ", FORMAT, ": ", the standard error string for errno,
and a newline, on stderr.  */
 extern void warn (const char *__format, ...)
- __attribute__ ((__format__ (__printf__, 1, 2)));
+ __attribute__ ((__format__ (__printf__, 1, 2))) __COLD;
 extern void vwarn (const char *__format, __gnuc_va_list)
- __attribute__ ((__format__ (__printf__, 1, 0)));
+ __attribute__ ((__format__ (__printf__, 1, 0))) __COLD;
 
 /* Likewise, but without ": " and the standard error string.  */
 extern void warnx (const char *__format, ...)
@@ -44,13 +44,13 @@ extern void vwarnx (const char *__format, __gnuc_va_list)
 
 /* Likewise, and then exit with STATUS.  */
 extern void err (int __status, const char *__format, ...)
- __attribute__ ((__noreturn__, __format__ (__printf__, 2, 3)));
+ __attribute__ ((__noreturn__, __format__ (__printf__, 2, 3))) __COLD;
 extern void verr (int __status, const char *__format, __gnuc_va_list)
- __attribute__ ((__noreturn__, __format__ (__printf__, 2, 0)));
+ __attribute__ ((__noreturn__, __format__ (__printf__, 2, 0))) __COLD;
 extern void errx (int __status, const char *__format, ...)
- __attribute__ ((__noreturn__, __format__ (__printf__, 2, 3)));
+ __attribute__ ((__noreturn__, __format__ (__printf__, 2, 3))) __COLD;
 extern void verrx (int __status, const char *, __gnuc_va_list)
- __attribute__ ((__noreturn__, __format__ (__printf__, 2, 0)));
+ __attribute__ ((__noreturn__, __format__ (__printf__, 2, 0))) __COLD;
 
 #include 
 #if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
diff --git a/misc/error.h b/misc/error.h
index 185b39c6..4fbd46c7 100644
--- a/misc/error.h
+++ b/misc/error.h
@@ -29,11 +29,11 @@ __BEGIN_DECLS
If STATUS is nonzero, terminate the program with `exit (STATUS)'.  */
 
 extern void error (int __status, int __errnum, const char *__format, ...)
- __attribute__ ((__format__ (__printf__, 3, 4)));
+ __attribute__ ((__format__ (__printf__, 3, 4))) __COLD;
 
 extern void error_at_line (int __status, int __errnum, const char *__fname,
   unsigned int __lineno, const char *__format, ...)
- __attribute__ ((__format__ (__printf__, 5, 6)));
+ __attribute__ ((__format__ (__printf__, 5, 6))) __COLD;
 
 /* If NULL, error will flush stdout, then print on stderr the program
name, a colon and a space.  Otherwise, error will call this
-- 
2.40.1




[PATCH 2/3] hurd: Mark error functions as __COLD

2023-04-29 Thread Sergey Bugaev
This should hopefully hint the compiler that they are unlikely
to be called.

Signed-off-by: Sergey Bugaev 
---
 hurd/hurd.h| 2 +-
 hurd/hurd/fd.h | 8 
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/hurd/hurd.h b/hurd/hurd.h
index eca4abb7..06f00e93 100644
--- a/hurd/hurd.h
+++ b/hurd/hurd.h
@@ -48,7 +48,7 @@
 #define _HURD_H_EXTERN_INLINE __extern_inline
 #endif
 
-extern int __hurd_fail (error_t err);
+extern int __hurd_fail (error_t err) __COLD;
 
 #ifdef __USE_EXTERN_INLINES
 _HURD_H_EXTERN_INLINE int
diff --git a/hurd/hurd/fd.h b/hurd/hurd/fd.h
index f6139544..241797bf 100644
--- a/hurd/hurd/fd.h
+++ b/hurd/hurd/fd.h
@@ -149,7 +149,7 @@ _hurd_fd_get (int fd)
 /* Check if ERR should generate a signal.
Returns the signal to take, or zero if none.  */
 
-extern int _hurd_fd_error_signal (error_t err);
+extern int _hurd_fd_error_signal (error_t err) __COLD;
 
 #ifdef __USE_EXTERN_INLINES
 _HURD_FD_H_EXTERN_INLINE int
@@ -174,7 +174,7 @@ _hurd_fd_error_signal (error_t err)
always use this function to handle errors from RPCs made on file
descriptor ports.  Some errors are translated into signals.  */
 
-extern error_t _hurd_fd_error (int fd, error_t err);
+extern error_t _hurd_fd_error (int fd, error_t err) __COLD;
 
 #ifdef __USE_EXTERN_INLINES
 _HURD_FD_H_EXTERN_INLINE error_t
@@ -194,7 +194,7 @@ _hurd_fd_error (int fd, error_t err)
 /* Handle error code ERR from an RPC on file descriptor FD's port.
Set `errno' to the appropriate error code, and always return -1.  */
 
-extern int __hurd_dfail (int fd, error_t err);
+extern int __hurd_dfail (int fd, error_t err) __COLD;
 
 #ifdef __USE_EXTERN_INLINES
 _HURD_FD_H_EXTERN_INLINE int
@@ -208,7 +208,7 @@ __hurd_dfail (int fd, error_t err)
 /* Likewise, but do not raise SIGPIPE on EPIPE if flags contain
MSG_NOSIGNAL.  */
 
-extern int __hurd_sockfail (int fd, int flags, error_t err);
+extern int __hurd_sockfail (int fd, int flags, error_t err) __COLD;
 
 #ifdef __USE_EXTERN_INLINES
 _HURD_FD_H_EXTERN_INLINE int
-- 
2.40.1




[PATCH 1/3] cdefs.h: Define __COLD

2023-04-29 Thread Sergey Bugaev
This expands to __attribute__ ((cold)) when supported. It should be
used to mark up functions that are invoked rarely.

Signed-off-by: Sergey Bugaev 
---

I can change __COLD to __attribute_cold__ if that is preferred.

 misc/sys/cdefs.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
index 23ec0ebd..8eec4b94 100644
--- a/misc/sys/cdefs.h
+++ b/misc/sys/cdefs.h
@@ -98,6 +98,12 @@
 #  endif
 # endif
 
+# if __GNUC_PREREQ (4, 3) || __glibc_has_attribute (__cold__)
+#  define __COLD   __attribute__ ((__cold__))
+# else
+#  define __COLD
+# endif
+
 #else  /* Not GCC or clang.  */
 
 # if (defined __cplusplus  \
-- 
2.40.1




[PATCH 1/7] hurd: Simplify _hurd_critical_section_lock a bit

2023-04-29 Thread Sergey Bugaev
This block of code was doing exactly what _hurd_self_sigstate does; so
just call that and let it do its job.

Signed-off-by: Sergey Bugaev 
---
 hurd/hurd/signal.h | 14 +-
 1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/hurd/hurd/signal.h b/hurd/hurd/signal.h
index 662e955e..302ca25e 100644
--- a/hurd/hurd/signal.h
+++ b/hurd/hurd/signal.h
@@ -218,19 +218,7 @@ _hurd_critical_section_lock (void)
 return NULL;
 #endif
 
-  ss = THREAD_GETMEM (THREAD_SELF, _hurd_sigstate);
-  if (ss == NULL)
-{
-  thread_t self = __mach_thread_self ();
-
-  /* The thread variable is unset; this must be the first time we've
-asked for it.  In this case, the critical section flag cannot
-possible already be set.  Look up our sigstate structure the slow
-way.  */
-  ss = _hurd_thread_sigstate (self);
-  THREAD_SETMEM (THREAD_SELF, _hurd_sigstate, ss);
-  __mach_port_deallocate (__mach_task_self (), self);
-}
+  ss = _hurd_self_sigstate ();
 
   if (! __spin_try_lock (&ss->critical_section_lock))
 /* We are already in a critical section, so do nothing.  */
-- 
2.40.1




[PATCH 2/7] hurd: Move libc_hidden_def's around

2023-04-29 Thread Sergey Bugaev
Each libc_hidden_def should be placed immediately next to its function,
not in some random unrelated place.

No functional change.

Fixes: 653d74f12abea144219af00400ed1f1ac5dfa79f
"hurd: Global signal disposition"

Signed-off-by: Sergey Bugaev 
---
 hurd/hurdsig.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
index c84de4db..78ea59d9 100644
--- a/hurd/hurdsig.c
+++ b/hurd/hurdsig.c
@@ -174,6 +174,7 @@ _hurd_sigstate_set_global_rcv (struct hurd_sigstate *ss)
   assert (ss->thread != MACH_PORT_NULL);
   ss->actions[0].sa_handler = SIG_IGN;
 }
+libc_hidden_def (_hurd_sigstate_set_global_rcv)
 
 /* Check whether SS is a global receiver.  */
 static int
@@ -193,6 +194,8 @@ _hurd_sigstate_lock (struct hurd_sigstate *ss)
 __spin_lock (&_hurd_global_sigstate->lock);
   __spin_lock (&ss->lock);
 }
+libc_hidden_def (_hurd_sigstate_lock)
+
 void
 _hurd_sigstate_unlock (struct hurd_sigstate *ss)
 {
@@ -200,7 +203,7 @@ _hurd_sigstate_unlock (struct hurd_sigstate *ss)
   if (sigstate_is_global_rcv (ss))
 __spin_unlock (&_hurd_global_sigstate->lock);
 }
-libc_hidden_def (_hurd_sigstate_set_global_rcv)
+libc_hidden_def (_hurd_sigstate_unlock)
 
 /* Retrieve a thread's full set of pending signals, including the global
ones if appropriate.  SS must be locked.  */
@@ -212,6 +215,7 @@ _hurd_sigstate_pending (const struct hurd_sigstate *ss)
 __sigorset (&pending, &pending, &_hurd_global_sigstate->pending);
   return pending;
 }
+libc_hidden_def (_hurd_sigstate_pending)
 
 /* Clear a pending signal and return the associated detailed
signal information. SS must be locked, and must have signal SIGNO
@@ -230,8 +234,6 @@ sigstate_clear_pending (struct hurd_sigstate *ss, int signo)
   __sigdelset (&ss->pending, signo);
   return ss->pending_data[signo];
 }
-libc_hidden_def (_hurd_sigstate_lock)
-libc_hidden_def (_hurd_sigstate_unlock)
 
 /* Retrieve a thread's action vector.  SS must be locked.  */
 struct sigaction *
@@ -242,7 +244,6 @@ _hurd_sigstate_actions (struct hurd_sigstate *ss)
   else
 return ss->actions;
 }
-libc_hidden_def (_hurd_sigstate_pending)
 
 
 /* Signal delivery itself is on this page.  */
-- 
2.40.1




[PATCH 5/7] hurd: Don't leak the auth port in msg* RPCs

2023-04-29 Thread Sergey Bugaev
The leak can be easily reproduced (and observed) using the portinfo
tool:

$ portinfo -v $$ | grep task
36: send task(1577)(self) (refs: 127)
$ portinfo -v $$ | grep task
36: send task(1577)(self) (refs: 253)
$ portinfo -v $$ | grep task
36: send task(1577)(self) (refs: 379)
$ portinfo -v $$ | grep task
36: send task(1577)(self) (refs: 505)
$ portinfo -v $$ | grep task
36: send task(1577)(self) (refs: 631)

Checked on i686-gnu.

Signed-off-by: Sergey Bugaev 
---
 hurd/hurdmsg.c | 67 +++---
 1 file changed, 58 insertions(+), 9 deletions(-)

diff --git a/hurd/hurdmsg.c b/hurd/hurdmsg.c
index 4bedd292..896fb87c 100644
--- a/hurd/hurdmsg.c
+++ b/hurd/hurdmsg.c
@@ -35,11 +35,17 @@ kern_return_t
   _S_msg_get_init_port (mach_port_t msgport, mach_port_t auth, int which,
mach_port_t *result, mach_msg_type_name_t *result_type)
 {
+  error_t err;
+
   AUTHCHECK;
+
   *result_type = MACH_MSG_TYPE_MOVE_SEND;
   /* This function adds a new user reference for the *RESULT it gives back.
  Our reply message uses a move-send right that consumes this reference.  */
-  return _hurd_ports_get (which, result);
+  err = _hurd_ports_get (which, result);
+  if (!err && MACH_PORT_VALID (auth))
+__mach_port_deallocate (__mach_task_self (), auth);
+  return err;
 }
 
 kern_return_t
@@ -51,10 +57,13 @@ _S_msg_set_init_port (mach_port_t msgport, mach_port_t auth,
   AUTHCHECK;
 
   err = _hurd_ports_set (which, port);
-  if (err == 0)
+
+  if (!err && MACH_PORT_VALID (port))
 __mach_port_deallocate (__mach_task_self (), port);
+  if (!err && MACH_PORT_VALID (auth))
+__mach_port_deallocate (__mach_task_self (), auth);
 
-  return 0;
+  return err;
 }
 
 kern_return_t
@@ -88,6 +97,8 @@ _S_msg_get_init_ports (mach_port_t msgport, mach_port_t auth,
   }
 
   *ports_type = MACH_MSG_TYPE_MOVE_SEND;
+  if (MACH_PORT_VALID (auth))
+__mach_port_deallocate (__mach_task_self (), auth);
   return 0;
 }
 
@@ -108,6 +119,8 @@ _S_msg_set_init_ports (mach_port_t msgport, mach_port_t 
auth,
__mach_port_deallocate (__mach_task_self (), ports[i]);
 }
 
+  if (MACH_PORT_VALID (auth))
+__mach_port_deallocate (__mach_task_self (), auth);
   return 0;
 }
 
@@ -152,9 +165,16 @@ kern_return_t
 _S_msg_get_init_int (mach_port_t msgport, mach_port_t auth,
 int which, int *value)
 {
+  error_t err;
+
   AUTHCHECK;
 
-  return get_int (which, value);
+  err = get_int (which, value);
+  if (err)
+return err;
+  if (MACH_PORT_VALID (auth))
+__mach_port_deallocate (__mach_task_self (), auth);
+  return 0;
 }
 
 kern_return_t
@@ -185,6 +205,8 @@ _S_msg_get_init_ints (mach_port_t msgport, mach_port_t auth,
return err;
   }
 
+  if (MACH_PORT_VALID (auth))
+__mach_port_deallocate (__mach_task_self (), auth);
   return 0;
 }
 
@@ -236,9 +258,16 @@ kern_return_t
 _S_msg_set_init_int (mach_port_t msgport, mach_port_t auth,
 int which, int value)
 {
+  error_t err;
+
   AUTHCHECK;
 
-  return set_int (which, value);
+  err = set_int (which, value);
+  if (err)
+return err;
+  if (MACH_PORT_VALID (auth))
+__mach_port_deallocate (__mach_task_self (), auth);
+  return 0;
 }
 
 kern_return_t
@@ -261,6 +290,8 @@ _S_msg_set_init_ints (mach_port_t msgport, mach_port_t auth,
return err;
   }
 
+  if (MACH_PORT_VALID (auth))
+__mach_port_deallocate (__mach_task_self (), auth);
   return 0;
 }
 
@@ -278,6 +309,8 @@ _S_msg_get_fd (mach_port_t msgport, mach_port_t auth, int 
which,
 return errno;
   *result_type = MACH_MSG_TYPE_MOVE_SEND;
 
+  if (MACH_PORT_VALID (auth))
+__mach_port_deallocate (__mach_task_self (), auth);
   return 0;
 }
 
@@ -285,17 +318,25 @@ kern_return_t
 _S_msg_set_fd (mach_port_t msgport, mach_port_t auth,
   int which, mach_port_t port)
 {
+  error_t err;
+
   AUTHCHECK;
 
   /* We consume the reference if successful.  */
-  return HURD_FD_USE (which, (_hurd_port2fd (descriptor, port, 0), 0));
+  err = HURD_FD_USE (which, (_hurd_port2fd (descriptor, port, 0), 0));
+  if (err)
+return err;
+
+  if (MACH_PORT_VALID (auth))
+__mach_port_deallocate (__mach_task_self (), auth);
+  return 0;
 }
 
 /* Snarfing and frobbing environment variables.  */
 
 kern_return_t
 _S_msg_get_env_variable (mach_port_t msgport,
-const_string_t variable, //
+const_string_t variable,
 char **data, mach_msg_type_number_t *datalen)
 {
   error_t err;
@@ -322,14 +363,17 @@ _S_msg_get_env_variable (mach_port_t msgport,
 
 kern_return_t
 _S_msg_set_env_variable (mach_port_t msgport, mach_port_t auth,
-const_string_t variable, //
-const_string_t value, //
+const_string_t variable,
+const_string_t value,
 int replace)
 {
   AUTHCHECK;
 
   if (__setenv (variable

[PATCH 6/7] hurd: Respect existing FD_CLOEXEC in S_msg_set_fd

2023-04-29 Thread Sergey Bugaev
If the process has set the close-on-exec flag for the file descriptor,
it expects the file descriptor to get closed on exec, even if we replace
what the file descriptor refers to.

Signed-off-by: Sergey Bugaev 
---
 hurd/hurdmsg.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/hurd/hurdmsg.c b/hurd/hurdmsg.c
index 896fb87c..8fde1f53 100644
--- a/hurd/hurdmsg.c
+++ b/hurd/hurdmsg.c
@@ -323,7 +323,13 @@ _S_msg_set_fd (mach_port_t msgport, mach_port_t auth,
   AUTHCHECK;
 
   /* We consume the reference if successful.  */
-  err = HURD_FD_USE (which, (_hurd_port2fd (descriptor, port, 0), 0));
+  err = HURD_FD_USE (which,
+({
+  int flags = (descriptor->flags & FD_CLOEXEC)
+  ? O_CLOEXEC : 0;
+  _hurd_port2fd (descriptor, port, flags);
+  0;
+}));
   if (err)
 return err;
 
-- 
2.40.1




[PATCH 7/7] hurd: Fix FS_RETRY_MAGICAL "machtype" handling

2023-04-29 Thread Sergey Bugaev
We need to set file_name, not update retryname. This is what the other
branches do.

Before this change, any attempt to access such a file would segfault due
to file_name being unset:

$ settrans -ac /tmp/my-machtype /hurd/magic machtype
$ cat /tmp/my-machtype
Segmentation fault

Checked on i686-gnu.

Signed-off-by: Sergey Bugaev 
---
 hurd/lookup-retry.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/hurd/lookup-retry.c b/hurd/lookup-retry.c
index 99c98104..62f94bbc 100644
--- a/hurd/lookup-retry.c
+++ b/hurd/lookup-retry.c
@@ -277,7 +277,6 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
  error_t err;
  struct host_basic_info hostinfo;
  mach_msg_type_number_t hostinfocnt = HOST_BASIC_INFO_COUNT;
- char *p;
  /* XXX want client's host */
  if (err = __host_info (__mach_host_self (), HOST_BASIC_INFO,
 (integer_t *) &hostinfo,
@@ -288,13 +287,11 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
  err = EGRATUITOUS;
  goto out;
}
- p = _itoa (hostinfo.cpu_subtype, &retryname[8], 10, 0);
- *--p = '/';
- p = _itoa (hostinfo.cpu_type, &retryname[8], 10, 0);
- if (p < retryname)
+ file_name = _itoa (hostinfo.cpu_subtype, &retryname[8], 10, 
0);
+ *--file_name = '/';
+ file_name = _itoa (hostinfo.cpu_type, file_name, 10, 0);
+ if (file_name < retryname)
abort ();   /* XXX write this right if this ever happens */
- if (p > retryname)
-   memmove (retryname, p, strlen(p) + 1);
  startdir = *result;
}
  else
-- 
2.40.1




[PATCH 4/7] hurd: Make _exit work during early boot-up

2023-04-29 Thread Sergey Bugaev
If any of the early boot-up tasks calls exit () or returns from main (),
terminate it properly instead of crashing on trying to dereference
_hurd_ports and getting forcibly terminated by the kernel.

We sadly cannot make the __USEPORT macro do the check for _hurd_ports
being unset, because it evaluates to the value of the expression
provided as the second argument, and that can be of any type; so there
is no single suitable fallback value for the macro to evaluate to in
case _hurd_ports is unset. Instead, each use site that wants to care for
this case will have to do its own checking.

Checked on x86_64-gnu.

Signed-off-by: Sergey Bugaev 
---
 sysdeps/mach/hurd/_exit.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/sysdeps/mach/hurd/_exit.c b/sysdeps/mach/hurd/_exit.c
index 73957744..80cfe532 100644
--- a/sysdeps/mach/hurd/_exit.c
+++ b/sysdeps/mach/hurd/_exit.c
@@ -24,8 +24,9 @@
 void
 _hurd_exit (int status)
 {
-  /* Give the proc server our exit status.  */
-  __USEPORT (PROC, __proc_mark_exit (port, status, 0));
+  if (_hurd_ports != NULL)
+/* Give the proc server our exit status.  */
+__USEPORT (PROC, __proc_mark_exit (port, status, 0));
 
   /* Commit suicide.  */
   __task_terminate (__mach_task_self ());
-- 
2.40.1




[PATCH 3/7] hurd: Mark various conditions as unlikely

2023-04-29 Thread Sergey Bugaev
Signed-off-by: Sergey Bugaev 
---
 hurd/hurd/fd.h | 10 +-
 hurd/hurd/signal.h |  4 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/hurd/hurd/fd.h b/hurd/hurd/fd.h
index 241797bf..824b7dbb 100644
--- a/hurd/hurd/fd.h
+++ b/hurd/hurd/fd.h
@@ -73,18 +73,18 @@ _hurd_fd_get (int fd)
 
   HURD_CRITICAL_BEGIN;
   __mutex_lock (&_hurd_dtable_lock);
-  if (fd < 0 || fd >= _hurd_dtablesize)
+  if (__glibc_unlikely (fd < 0 || fd >= _hurd_dtablesize))
 descriptor = NULL;
   else
 {
   struct hurd_fd *cell = _hurd_dtable[fd];
-  if (cell == NULL)
+  if (__glibc_unlikely (cell == NULL))
/* No descriptor allocated at this index.  */
descriptor = NULL;
   else
{
  __spin_lock (&cell->port.lock);
- if (cell->port.port == MACH_PORT_NULL)
+ if (__glibc_unlikely (cell->port.port == MACH_PORT_NULL))
/* The descriptor at this index has no port in it.
   This happens if it existed before but was closed.  */
descriptor = NULL;
@@ -107,7 +107,7 @@ _hurd_fd_get (int fd)
 
 #defineHURD_FD_USE(fd, expr)   
  \
   ({ struct hurd_fd *descriptor = _hurd_fd_get (fd); \
- descriptor == NULL ? EBADF : (expr); })
+ __glibc_unlikely (descriptor == NULL) ? EBADF : (expr); })
 
 /* Evaluate EXPR with the variable `port' bound to the port to FD, and
`ctty' bound to the ctty port.  */
@@ -125,7 +125,7 @@ _hurd_fd_get (int fd)
  io_t port, ctty;\
  void *crit = _hurd_critical_section_lock ();\
  __spin_lock (&__d->port.lock);  \
- if (__d->port.port == MACH_PORT_NULL)   \
+ if (__glibc_unlikely (__d->port.port == MACH_PORT_NULL))\
{ \
 __spin_unlock (&__d->port.lock); \
 _hurd_critical_section_unlock (crit);\
diff --git a/hurd/hurd/signal.h b/hurd/hurd/signal.h
index 302ca25e..8a547fd0 100644
--- a/hurd/hurd/signal.h
+++ b/hurd/hurd/signal.h
@@ -249,9 +249,9 @@ _hurd_critical_section_unlock (void *our_lock)
   sigset_t pending;
   _hurd_sigstate_lock (ss);
   __spin_unlock (&ss->critical_section_lock);
-  pending = _hurd_sigstate_pending(ss) & ~ss->blocked;
+  pending = _hurd_sigstate_pending (ss) & ~ss->blocked;
   _hurd_sigstate_unlock (ss);
-  if (! __sigisemptyset (&pending))
+  if (__glibc_unlikely (!__sigisemptyset (&pending)))
/* There are unblocked signals pending, which weren't
   delivered because we were in the critical section.
   Tell the signal thread to deliver them now.  */
-- 
2.40.1




Re: [PATCH] cdefs.h: Define __COLD

2023-04-29 Thread Sergey Bugaev
And of course right after I have sent it, I notice that I forgot the
"Not GCC or clang." case.

Sergey

-- >8 --

>From 1b8c6563828399de563846525d0f525001f2d80d Mon Sep 17 00:00:00 2001
From: Sergey Bugaev 
Date: Thu, 27 Apr 2023 17:42:11 +0300
Subject: [PATCH] cdefs.h: Define __COLD

This expands to __attribute__ ((cold)) when supported. It should be
used to mark up functions that are invoked rarely.

Signed-off-by: Sergey Bugaev 
---
 misc/sys/cdefs.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
index 23ec0ebd..9a07e297 100644
--- a/misc/sys/cdefs.h
+++ b/misc/sys/cdefs.h
@@ -98,6 +98,12 @@
 #  endif
 # endif
 
+# if __GNUC_PREREQ (4, 3) || __glibc_has_attribute (__cold__)
+#  define __COLD   __attribute__ ((__cold__))
+# else
+#  define __COLD
+# endif
+
 #else  /* Not GCC or clang.  */
 
 # if (defined __cplusplus  \
@@ -110,6 +116,7 @@
 # define __THROW
 # define __THROWNL
 # define __NTH(fct)fct
+# define __COLD
 
 #endif /* GCC || clang.  */
 
-- 
2.40.1




Re: Mach time device, or: I know why the network deadlocks!

2023-04-29 Thread Sergey Bugaev
On Sat, Apr 29, 2023 at 7:39 AM Flávio Cruz  wrote:
> This never happened to me. Probably because I don't have NTP installed
> in my Hurd box?

That might explain it :)

But I can't be the only one who wants their Hurd VM to have a sane
notion of the current time across suspend-wake cycles of the host
machine , can I?

>> Since we have already broken ABI compatibility with the time device on
>> other Mach versions (if it ever existed) by adding the *64 variants to
>> the struct mapped_time_value, maybe we could just place the
>> clock_boottime_offset into the same struct? Then the userspace would
>> be able to pick it up and use it to calculate the boottime-relative
>> time.
>
> User land can still use the old time structures but can now be updated to 
> read the
> *64 variants.

Yes; what I mean is that they can't use the new data unconditionally,
since they could be running on older GNU Mach, or theoretically on
some non-GNU Mach (although that would not work anymore for many other
reasons).

> I think the approach makes sense to me. We can update the 
> clock_boottime_offset
> in the structure whenever it is updated by the kernel and then provide a
> maptime_read(clockid_t clock, struct mapped_time_value *mtime, struct timeval 
> *tv)
> routine to read from the mapped memory and return either a time using 
> CLOCK_REALTIME
> or CLOCK_MONOTONIC semantics.

But we cannot just change the signature of maptime_read like that
because we haven't been versioning the symbols. (Which we should
really start doing: as the old saying goes, the best time to start
versioning your symbols was when you first wrote your shared library;
the second best time is now.) It'd have to be a separate function,
perhaps maptime_read_clock or maptime_clockread.

> We could also have an RPC host_get_time that is parameterized by clockid_t to 
> have some
> symmetry with the routine above.

Do we really have a concept of clockid in the kernel?

Sergey



Re: [PATCH 1/7] hurd: Simplify _hurd_critical_section_lock a bit

2023-04-29 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le sam. 29 avril 2023 16:13:48 +0300, a ecrit:
> This block of code was doing exactly what _hurd_self_sigstate does; so
> just call that and let it do its job.
> 
> Signed-off-by: Sergey Bugaev 
> ---
>  hurd/hurd/signal.h | 14 +-
>  1 file changed, 1 insertion(+), 13 deletions(-)
> 
> diff --git a/hurd/hurd/signal.h b/hurd/hurd/signal.h
> index 662e955e..302ca25e 100644
> --- a/hurd/hurd/signal.h
> +++ b/hurd/hurd/signal.h
> @@ -218,19 +218,7 @@ _hurd_critical_section_lock (void)
>  return NULL;
>  #endif
>  
> -  ss = THREAD_GETMEM (THREAD_SELF, _hurd_sigstate);
> -  if (ss == NULL)
> -{
> -  thread_t self = __mach_thread_self ();
> -
> -  /* The thread variable is unset; this must be the first time we've
> -  asked for it.  In this case, the critical section flag cannot
> -  possible already be set.  Look up our sigstate structure the slow
> -  way.  */
> -  ss = _hurd_thread_sigstate (self);
> -  THREAD_SETMEM (THREAD_SELF, _hurd_sigstate, ss);
> -  __mach_port_deallocate (__mach_task_self (), self);
> -}
> +  ss = _hurd_self_sigstate ();
>  
>if (! __spin_try_lock (&ss->critical_section_lock))
>  /* We are already in a critical section, so do nothing.  */
> -- 
> 2.40.1
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 2/7] hurd: Move libc_hidden_def's around

2023-04-29 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev via Libc-alpha, le sam. 29 avril 2023 16:13:49 +0300, a ecrit:
> Each libc_hidden_def should be placed immediately next to its function,
> not in some random unrelated place.
> 
> No functional change.
> 
> Fixes: 653d74f12abea144219af00400ed1f1ac5dfa79f
> "hurd: Global signal disposition"
> 
> Signed-off-by: Sergey Bugaev 
> ---
>  hurd/hurdsig.c | 9 +
>  1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
> index c84de4db..78ea59d9 100644
> --- a/hurd/hurdsig.c
> +++ b/hurd/hurdsig.c
> @@ -174,6 +174,7 @@ _hurd_sigstate_set_global_rcv (struct hurd_sigstate *ss)
>assert (ss->thread != MACH_PORT_NULL);
>ss->actions[0].sa_handler = SIG_IGN;
>  }
> +libc_hidden_def (_hurd_sigstate_set_global_rcv)
>  
>  /* Check whether SS is a global receiver.  */
>  static int
> @@ -193,6 +194,8 @@ _hurd_sigstate_lock (struct hurd_sigstate *ss)
>  __spin_lock (&_hurd_global_sigstate->lock);
>__spin_lock (&ss->lock);
>  }
> +libc_hidden_def (_hurd_sigstate_lock)
> +
>  void
>  _hurd_sigstate_unlock (struct hurd_sigstate *ss)
>  {
> @@ -200,7 +203,7 @@ _hurd_sigstate_unlock (struct hurd_sigstate *ss)
>if (sigstate_is_global_rcv (ss))
>  __spin_unlock (&_hurd_global_sigstate->lock);
>  }
> -libc_hidden_def (_hurd_sigstate_set_global_rcv)
> +libc_hidden_def (_hurd_sigstate_unlock)
>  
>  /* Retrieve a thread's full set of pending signals, including the global
> ones if appropriate.  SS must be locked.  */
> @@ -212,6 +215,7 @@ _hurd_sigstate_pending (const struct hurd_sigstate *ss)
>  __sigorset (&pending, &pending, &_hurd_global_sigstate->pending);
>return pending;
>  }
> +libc_hidden_def (_hurd_sigstate_pending)
>  
>  /* Clear a pending signal and return the associated detailed
> signal information. SS must be locked, and must have signal SIGNO
> @@ -230,8 +234,6 @@ sigstate_clear_pending (struct hurd_sigstate *ss, int 
> signo)
>__sigdelset (&ss->pending, signo);
>return ss->pending_data[signo];
>  }
> -libc_hidden_def (_hurd_sigstate_lock)
> -libc_hidden_def (_hurd_sigstate_unlock)
>  
>  /* Retrieve a thread's action vector.  SS must be locked.  */
>  struct sigaction *
> @@ -242,7 +244,6 @@ _hurd_sigstate_actions (struct hurd_sigstate *ss)
>else
>  return ss->actions;
>  }
> -libc_hidden_def (_hurd_sigstate_pending)
>  
>  
>  /* Signal delivery itself is on this page.  */
> -- 
> 2.40.1
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 3/7] hurd: Mark various conditions as unlikely

2023-04-29 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le sam. 29 avril 2023 16:13:50 +0300, a ecrit:
> Signed-off-by: Sergey Bugaev 
> ---
>  hurd/hurd/fd.h | 10 +-
>  hurd/hurd/signal.h |  4 ++--
>  2 files changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/hurd/hurd/fd.h b/hurd/hurd/fd.h
> index 241797bf..824b7dbb 100644
> --- a/hurd/hurd/fd.h
> +++ b/hurd/hurd/fd.h
> @@ -73,18 +73,18 @@ _hurd_fd_get (int fd)
>  
>HURD_CRITICAL_BEGIN;
>__mutex_lock (&_hurd_dtable_lock);
> -  if (fd < 0 || fd >= _hurd_dtablesize)
> +  if (__glibc_unlikely (fd < 0 || fd >= _hurd_dtablesize))
>  descriptor = NULL;
>else
>  {
>struct hurd_fd *cell = _hurd_dtable[fd];
> -  if (cell == NULL)
> +  if (__glibc_unlikely (cell == NULL))
>   /* No descriptor allocated at this index.  */
>   descriptor = NULL;
>else
>   {
> __spin_lock (&cell->port.lock);
> -   if (cell->port.port == MACH_PORT_NULL)
> +   if (__glibc_unlikely (cell->port.port == MACH_PORT_NULL))
>   /* The descriptor at this index has no port in it.
>  This happens if it existed before but was closed.  */
>   descriptor = NULL;
> @@ -107,7 +107,7 @@ _hurd_fd_get (int fd)
>  
>  #define  HURD_FD_USE(fd, expr)   
>   \
>({ struct hurd_fd *descriptor = _hurd_fd_get (fd);   \
> - descriptor == NULL ? EBADF : (expr); })
> + __glibc_unlikely (descriptor == NULL) ? EBADF : (expr); })
>  
>  /* Evaluate EXPR with the variable `port' bound to the port to FD, and
> `ctty' bound to the ctty port.  */
> @@ -125,7 +125,7 @@ _hurd_fd_get (int fd)
>   io_t port, ctty;
>   \
>   void *crit = _hurd_critical_section_lock ();  \
>   __spin_lock (&__d->port.lock);\
> - if (__d->port.port == MACH_PORT_NULL) \
> + if (__glibc_unlikely (__d->port.port == MACH_PORT_NULL))
>   \
> {   \
>__spin_unlock (&__d->port.lock); \
>_hurd_critical_section_unlock (crit);\
> diff --git a/hurd/hurd/signal.h b/hurd/hurd/signal.h
> index 302ca25e..8a547fd0 100644
> --- a/hurd/hurd/signal.h
> +++ b/hurd/hurd/signal.h
> @@ -249,9 +249,9 @@ _hurd_critical_section_unlock (void *our_lock)
>sigset_t pending;
>_hurd_sigstate_lock (ss);
>__spin_unlock (&ss->critical_section_lock);
> -  pending = _hurd_sigstate_pending(ss) & ~ss->blocked;
> +  pending = _hurd_sigstate_pending (ss) & ~ss->blocked;
>_hurd_sigstate_unlock (ss);
> -  if (! __sigisemptyset (&pending))
> +  if (__glibc_unlikely (!__sigisemptyset (&pending)))
>   /* There are unblocked signals pending, which weren't
>  delivered because we were in the critical section.
>  Tell the signal thread to deliver them now.  */
> -- 
> 2.40.1
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 4/7] hurd: Make _exit work during early boot-up

2023-04-29 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le sam. 29 avril 2023 16:13:51 +0300, a ecrit:
> If any of the early boot-up tasks calls exit () or returns from main (),
> terminate it properly instead of crashing on trying to dereference
> _hurd_ports and getting forcibly terminated by the kernel.
> 
> We sadly cannot make the __USEPORT macro do the check for _hurd_ports
> being unset, because it evaluates to the value of the expression
> provided as the second argument, and that can be of any type; so there
> is no single suitable fallback value for the macro to evaluate to in
> case _hurd_ports is unset. Instead, each use site that wants to care for
> this case will have to do its own checking.
> 
> Checked on x86_64-gnu.

\o/

> Signed-off-by: Sergey Bugaev 
> ---
>  sysdeps/mach/hurd/_exit.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/sysdeps/mach/hurd/_exit.c b/sysdeps/mach/hurd/_exit.c
> index 73957744..80cfe532 100644
> --- a/sysdeps/mach/hurd/_exit.c
> +++ b/sysdeps/mach/hurd/_exit.c
> @@ -24,8 +24,9 @@
>  void
>  _hurd_exit (int status)
>  {
> -  /* Give the proc server our exit status.  */
> -  __USEPORT (PROC, __proc_mark_exit (port, status, 0));
> +  if (_hurd_ports != NULL)
> +/* Give the proc server our exit status.  */
> +__USEPORT (PROC, __proc_mark_exit (port, status, 0));
>  
>/* Commit suicide.  */
>__task_terminate (__mach_task_self ());
> -- 
> 2.40.1
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 5/7] hurd: Don't leak the auth port in msg* RPCs

2023-04-29 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le sam. 29 avril 2023 16:13:52 +0300, a ecrit:
> The leak can be easily reproduced (and observed) using the portinfo
> tool:
> 
> $ portinfo -v $$ | grep task
> 36: send task(1577)(self) (refs: 127)
> $ portinfo -v $$ | grep task
> 36: send task(1577)(self) (refs: 253)
> $ portinfo -v $$ | grep task
> 36: send task(1577)(self) (refs: 379)
> $ portinfo -v $$ | grep task
> 36: send task(1577)(self) (refs: 505)
> $ portinfo -v $$ | grep task
> 36: send task(1577)(self) (refs: 631)
> 
> Checked on i686-gnu.
> 
> Signed-off-by: Sergey Bugaev 
> ---
>  hurd/hurdmsg.c | 67 +++---
>  1 file changed, 58 insertions(+), 9 deletions(-)
> 
> diff --git a/hurd/hurdmsg.c b/hurd/hurdmsg.c
> index 4bedd292..896fb87c 100644
> --- a/hurd/hurdmsg.c
> +++ b/hurd/hurdmsg.c
> @@ -35,11 +35,17 @@ kern_return_t
>_S_msg_get_init_port (mach_port_t msgport, mach_port_t auth, int which,
>   mach_port_t *result, mach_msg_type_name_t *result_type)
>  {
> +  error_t err;
> +
>AUTHCHECK;
> +
>*result_type = MACH_MSG_TYPE_MOVE_SEND;
>/* This function adds a new user reference for the *RESULT it gives back.
>   Our reply message uses a move-send right that consumes this reference.  
> */
> -  return _hurd_ports_get (which, result);
> +  err = _hurd_ports_get (which, result);
> +  if (!err && MACH_PORT_VALID (auth))
> +__mach_port_deallocate (__mach_task_self (), auth);
> +  return err;
>  }
>  
>  kern_return_t
> @@ -51,10 +57,13 @@ _S_msg_set_init_port (mach_port_t msgport, mach_port_t 
> auth,
>AUTHCHECK;
>  
>err = _hurd_ports_set (which, port);
> -  if (err == 0)
> +
> +  if (!err && MACH_PORT_VALID (port))
>  __mach_port_deallocate (__mach_task_self (), port);
> +  if (!err && MACH_PORT_VALID (auth))
> +__mach_port_deallocate (__mach_task_self (), auth);
>  
> -  return 0;
> +  return err;
>  }
>  
>  kern_return_t
> @@ -88,6 +97,8 @@ _S_msg_get_init_ports (mach_port_t msgport, mach_port_t 
> auth,
>}
>  
>*ports_type = MACH_MSG_TYPE_MOVE_SEND;
> +  if (MACH_PORT_VALID (auth))
> +__mach_port_deallocate (__mach_task_self (), auth);
>return 0;
>  }
>  
> @@ -108,6 +119,8 @@ _S_msg_set_init_ports (mach_port_t msgport, mach_port_t 
> auth,
>   __mach_port_deallocate (__mach_task_self (), ports[i]);
>  }
>  
> +  if (MACH_PORT_VALID (auth))
> +__mach_port_deallocate (__mach_task_self (), auth);
>return 0;
>  }
>  
> @@ -152,9 +165,16 @@ kern_return_t
>  _S_msg_get_init_int (mach_port_t msgport, mach_port_t auth,
>int which, int *value)
>  {
> +  error_t err;
> +
>AUTHCHECK;
>  
> -  return get_int (which, value);
> +  err = get_int (which, value);
> +  if (err)
> +return err;
> +  if (MACH_PORT_VALID (auth))
> +__mach_port_deallocate (__mach_task_self (), auth);
> +  return 0;
>  }
>  
>  kern_return_t
> @@ -185,6 +205,8 @@ _S_msg_get_init_ints (mach_port_t msgport, mach_port_t 
> auth,
>   return err;
>}
>  
> +  if (MACH_PORT_VALID (auth))
> +__mach_port_deallocate (__mach_task_self (), auth);
>return 0;
>  }
>  
> @@ -236,9 +258,16 @@ kern_return_t
>  _S_msg_set_init_int (mach_port_t msgport, mach_port_t auth,
>int which, int value)
>  {
> +  error_t err;
> +
>AUTHCHECK;
>  
> -  return set_int (which, value);
> +  err = set_int (which, value);
> +  if (err)
> +return err;
> +  if (MACH_PORT_VALID (auth))
> +__mach_port_deallocate (__mach_task_self (), auth);
> +  return 0;
>  }
>  
>  kern_return_t
> @@ -261,6 +290,8 @@ _S_msg_set_init_ints (mach_port_t msgport, mach_port_t 
> auth,
>   return err;
>}
>  
> +  if (MACH_PORT_VALID (auth))
> +__mach_port_deallocate (__mach_task_self (), auth);
>return 0;
>  }
>  
> @@ -278,6 +309,8 @@ _S_msg_get_fd (mach_port_t msgport, mach_port_t auth, int 
> which,
>  return errno;
>*result_type = MACH_MSG_TYPE_MOVE_SEND;
>  
> +  if (MACH_PORT_VALID (auth))
> +__mach_port_deallocate (__mach_task_self (), auth);
>return 0;
>  }
>  
> @@ -285,17 +318,25 @@ kern_return_t
>  _S_msg_set_fd (mach_port_t msgport, mach_port_t auth,
>  int which, mach_port_t port)
>  {
> +  error_t err;
> +
>AUTHCHECK;
>  
>/* We consume the reference if successful.  */
> -  return HURD_FD_USE (which, (_hurd_port2fd (descriptor, port, 0), 0));
> +  err = HURD_FD_USE (which, (_hurd_port2fd (descriptor, port, 0), 0));
> +  if (err)
> +return err;
> +
> +  if (MACH_PORT_VALID (auth))
> +__mach_port_deallocate (__mach_task_self (), auth);
> +  return 0;
>  }
>  
>  /* Snarfing and frobbing environment variables.  */
>  
>  kern_return_t
>  _S_msg_get_env_variable (mach_port_t msgport,
> -  const_string_t variable, //
> +  const_string_t variable,
>char **data, mach_msg_type_number_t *datalen)
>  {
>error_t err;
> @@ -322,14 +3

Re: [PATCH 6/7] hurd: Respect existing FD_CLOEXEC in S_msg_set_fd

2023-04-29 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le sam. 29 avril 2023 16:13:53 +0300, a ecrit:
> If the process has set the close-on-exec flag for the file descriptor,
> it expects the file descriptor to get closed on exec, even if we replace
> what the file descriptor refers to.
> 
> Signed-off-by: Sergey Bugaev 
> ---
>  hurd/hurdmsg.c | 8 +++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/hurd/hurdmsg.c b/hurd/hurdmsg.c
> index 896fb87c..8fde1f53 100644
> --- a/hurd/hurdmsg.c
> +++ b/hurd/hurdmsg.c
> @@ -323,7 +323,13 @@ _S_msg_set_fd (mach_port_t msgport, mach_port_t auth,
>AUTHCHECK;
>  
>/* We consume the reference if successful.  */
> -  err = HURD_FD_USE (which, (_hurd_port2fd (descriptor, port, 0), 0));
> +  err = HURD_FD_USE (which,
> +  ({
> +int flags = (descriptor->flags & FD_CLOEXEC)
> +? O_CLOEXEC : 0;
> +_hurd_port2fd (descriptor, port, flags);
> +0;
> +  }));
>if (err)
>  return err;
>  
> -- 
> 2.40.1
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 7/7] hurd: Fix FS_RETRY_MAGICAL "machtype" handling

2023-04-29 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le sam. 29 avril 2023 16:13:54 +0300, a ecrit:
> We need to set file_name, not update retryname. This is what the other
> branches do.
> 
> Before this change, any attempt to access such a file would segfault due
> to file_name being unset:
> 
> $ settrans -ac /tmp/my-machtype /hurd/magic machtype
> $ cat /tmp/my-machtype
> Segmentation fault
> 
> Checked on i686-gnu.
> 
> Signed-off-by: Sergey Bugaev 
> ---
>  hurd/lookup-retry.c | 11 ---
>  1 file changed, 4 insertions(+), 7 deletions(-)
> 
> diff --git a/hurd/lookup-retry.c b/hurd/lookup-retry.c
> index 99c98104..62f94bbc 100644
> --- a/hurd/lookup-retry.c
> +++ b/hurd/lookup-retry.c
> @@ -277,7 +277,6 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
> error_t err;
> struct host_basic_info hostinfo;
> mach_msg_type_number_t hostinfocnt = HOST_BASIC_INFO_COUNT;
> -   char *p;
> /* XXX want client's host */
> if (err = __host_info (__mach_host_self (), HOST_BASIC_INFO,
>(integer_t *) &hostinfo,
> @@ -288,13 +287,11 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
> err = EGRATUITOUS;
> goto out;
>   }
> -   p = _itoa (hostinfo.cpu_subtype, &retryname[8], 10, 0);
> -   *--p = '/';
> -   p = _itoa (hostinfo.cpu_type, &retryname[8], 10, 0);
> -   if (p < retryname)
> +   file_name = _itoa (hostinfo.cpu_subtype, &retryname[8], 10, 
> 0);
> +   *--file_name = '/';
> +   file_name = _itoa (hostinfo.cpu_type, file_name, 10, 0);
> +   if (file_name < retryname)
>   abort ();   /* XXX write this right if this ever happens */
> -   if (p > retryname)
> - memmove (retryname, p, strlen(p) + 1);
> startdir = *result;
>   }
> else
> -- 
> 2.40.1
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH] cdefs.h: Define __COLD

2023-04-29 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le sam. 29 avril 2023 16:20:53 +0300, a ecrit:
> And of course right after I have sent it, I notice that I forgot the
> "Not GCC or clang." case.
> 
> Sergey
> 
> -- >8 --
> 
> From 1b8c6563828399de563846525d0f525001f2d80d Mon Sep 17 00:00:00 2001
> From: Sergey Bugaev 
> Date: Thu, 27 Apr 2023 17:42:11 +0300
> Subject: [PATCH] cdefs.h: Define __COLD
> 
> This expands to __attribute__ ((cold)) when supported. It should be
> used to mark up functions that are invoked rarely.
> 
> Signed-off-by: Sergey Bugaev 
> ---
>  misc/sys/cdefs.h | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
> index 23ec0ebd..9a07e297 100644
> --- a/misc/sys/cdefs.h
> +++ b/misc/sys/cdefs.h
> @@ -98,6 +98,12 @@
>  #  endif
>  # endif
>  
> +# if __GNUC_PREREQ (4, 3) || __glibc_has_attribute (__cold__)
> +#  define __COLD __attribute__ ((__cold__))
> +# else
> +#  define __COLD
> +# endif
> +
>  #else/* Not GCC or clang.  */
>  
>  # if (defined __cplusplus\
> @@ -110,6 +116,7 @@
>  # define __THROW
>  # define __THROWNL
>  # define __NTH(fct)  fct
> +# define __COLD
>  
>  #endif   /* GCC || clang.  */
>  
> -- 
> 2.40.1
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 2/3] hurd: Mark error functions as __COLD

2023-04-29 Thread Samuel Thibault
Applied, thanks!

Sergey Bugaev, le sam. 29 avril 2023 16:12:22 +0300, a ecrit:
> This should hopefully hint the compiler that they are unlikely
> to be called.
> 
> Signed-off-by: Sergey Bugaev 
> ---
>  hurd/hurd.h| 2 +-
>  hurd/hurd/fd.h | 8 
>  2 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/hurd/hurd.h b/hurd/hurd.h
> index eca4abb7..06f00e93 100644
> --- a/hurd/hurd.h
> +++ b/hurd/hurd.h
> @@ -48,7 +48,7 @@
>  #define _HURD_H_EXTERN_INLINE __extern_inline
>  #endif
>  
> -extern int __hurd_fail (error_t err);
> +extern int __hurd_fail (error_t err) __COLD;
>  
>  #ifdef __USE_EXTERN_INLINES
>  _HURD_H_EXTERN_INLINE int
> diff --git a/hurd/hurd/fd.h b/hurd/hurd/fd.h
> index f6139544..241797bf 100644
> --- a/hurd/hurd/fd.h
> +++ b/hurd/hurd/fd.h
> @@ -149,7 +149,7 @@ _hurd_fd_get (int fd)
>  /* Check if ERR should generate a signal.
> Returns the signal to take, or zero if none.  */
>  
> -extern int _hurd_fd_error_signal (error_t err);
> +extern int _hurd_fd_error_signal (error_t err) __COLD;
>  
>  #ifdef __USE_EXTERN_INLINES
>  _HURD_FD_H_EXTERN_INLINE int
> @@ -174,7 +174,7 @@ _hurd_fd_error_signal (error_t err)
> always use this function to handle errors from RPCs made on file
> descriptor ports.  Some errors are translated into signals.  */
>  
> -extern error_t _hurd_fd_error (int fd, error_t err);
> +extern error_t _hurd_fd_error (int fd, error_t err) __COLD;
>  
>  #ifdef __USE_EXTERN_INLINES
>  _HURD_FD_H_EXTERN_INLINE error_t
> @@ -194,7 +194,7 @@ _hurd_fd_error (int fd, error_t err)
>  /* Handle error code ERR from an RPC on file descriptor FD's port.
> Set `errno' to the appropriate error code, and always return -1.  */
>  
> -extern int __hurd_dfail (int fd, error_t err);
> +extern int __hurd_dfail (int fd, error_t err) __COLD;
>  
>  #ifdef __USE_EXTERN_INLINES
>  _HURD_FD_H_EXTERN_INLINE int
> @@ -208,7 +208,7 @@ __hurd_dfail (int fd, error_t err)
>  /* Likewise, but do not raise SIGPIPE on EPIPE if flags contain
> MSG_NOSIGNAL.  */
>  
> -extern int __hurd_sockfail (int fd, int flags, error_t err);
> +extern int __hurd_sockfail (int fd, int flags, error_t err) __COLD;
>  
>  #ifdef __USE_EXTERN_INLINES
>  _HURD_FD_H_EXTERN_INLINE int
> -- 
> 2.40.1
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH 3/3] Mark various cold functions as __COLD

2023-04-29 Thread Samuel Thibault
It looks sensible to me indeed, any opinion from somebody else?




Sergey Bugaev, le sam. 29 avril 2023 16:12:23 +0300, a ecrit:
> GCC docs explicitly list perror () as a good candidate for using
> __attribute__ ((cold)). So apply __COLD to perror () and similar
> functions.
> 
> Signed-off-by: Sergey Bugaev 
> ---
>  include/error.h |  4 ++--
>  libio/stdio.h   |  2 +-
>  misc/err.h  | 12 ++--
>  misc/error.h|  4 ++--
>  4 files changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/include/error.h b/include/error.h
> index 9e96262f..4db67cba 100644
> --- a/include/error.h
> +++ b/include/error.h
> @@ -5,11 +5,11 @@
>  
>  void
>  __error_internal (int status, int errnum, const char *message,
> -   va_list args, unsigned int mode_flags);
> +   va_list args, unsigned int mode_flags) __COLD;
>  
>  void
>  __error_at_line_internal (int status, int errnum, const char *file_name,
> unsigned int line_number, const char *message,
> -   va_list args, unsigned int mode_flags);
> +   va_list args, unsigned int mode_flags) __COLD;
>  
>  #endif
> diff --git a/libio/stdio.h b/libio/stdio.h
> index 45ddafdf..2387590d 100644
> --- a/libio/stdio.h
> +++ b/libio/stdio.h
> @@ -859,7 +859,7 @@ extern int ferror_unlocked (FILE *__stream) __THROW __wur;
>  
> This function is a possible cancellation point and therefore not
> marked with __THROW.  */
> -extern void perror (const char *__s);
> +extern void perror (const char *__s) __COLD;
>  
>  
>  #ifdef   __USE_POSIX
> diff --git a/misc/err.h b/misc/err.h
> index 0c752465..43df3a57 100644
> --- a/misc/err.h
> +++ b/misc/err.h
> @@ -32,9 +32,9 @@ __BEGIN_DECLS
>  /* Print "program: ", FORMAT, ": ", the standard error string for errno,
> and a newline, on stderr.  */
>  extern void warn (const char *__format, ...)
> - __attribute__ ((__format__ (__printf__, 1, 2)));
> + __attribute__ ((__format__ (__printf__, 1, 2))) __COLD;
>  extern void vwarn (const char *__format, __gnuc_va_list)
> - __attribute__ ((__format__ (__printf__, 1, 0)));
> + __attribute__ ((__format__ (__printf__, 1, 0))) __COLD;
>  
>  /* Likewise, but without ": " and the standard error string.  */
>  extern void warnx (const char *__format, ...)
> @@ -44,13 +44,13 @@ extern void vwarnx (const char *__format, __gnuc_va_list)
>  
>  /* Likewise, and then exit with STATUS.  */
>  extern void err (int __status, const char *__format, ...)
> - __attribute__ ((__noreturn__, __format__ (__printf__, 2, 3)));
> + __attribute__ ((__noreturn__, __format__ (__printf__, 2, 3))) __COLD;
>  extern void verr (int __status, const char *__format, __gnuc_va_list)
> - __attribute__ ((__noreturn__, __format__ (__printf__, 2, 0)));
> + __attribute__ ((__noreturn__, __format__ (__printf__, 2, 0))) __COLD;
>  extern void errx (int __status, const char *__format, ...)
> - __attribute__ ((__noreturn__, __format__ (__printf__, 2, 3)));
> + __attribute__ ((__noreturn__, __format__ (__printf__, 2, 3))) __COLD;
>  extern void verrx (int __status, const char *, __gnuc_va_list)
> - __attribute__ ((__noreturn__, __format__ (__printf__, 2, 0)));
> + __attribute__ ((__noreturn__, __format__ (__printf__, 2, 0))) __COLD;
>  
>  #include 
>  #if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
> diff --git a/misc/error.h b/misc/error.h
> index 185b39c6..4fbd46c7 100644
> --- a/misc/error.h
> +++ b/misc/error.h
> @@ -29,11 +29,11 @@ __BEGIN_DECLS
> If STATUS is nonzero, terminate the program with `exit (STATUS)'.  */
>  
>  extern void error (int __status, int __errnum, const char *__format, ...)
> - __attribute__ ((__format__ (__printf__, 3, 4)));
> + __attribute__ ((__format__ (__printf__, 3, 4))) __COLD;
>  
>  extern void error_at_line (int __status, int __errnum, const char *__fname,
>  unsigned int __lineno, const char *__format, ...)
> - __attribute__ ((__format__ (__printf__, 5, 6)));
> + __attribute__ ((__format__ (__printf__, 5, 6))) __COLD;
>  
>  /* If NULL, error will flush stdout, then print on stderr the program
> name, a colon and a space.  Otherwise, error will call this
> -- 
> 2.40.1
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



Re: [PATCH gnumach] Use c_string for dev_name_t in the device subsystem.

2023-04-29 Thread Samuel Thibault
Applied, thanks!

Flavio Cruz, le mer. 26 avril 2023 01:22:53 -0400, a ecrit:
> Added device_open_new and device_open_new_request and reused the old MiG
> ID for xxx_device_set_status which has not been in used in the past
> decade.
> 
> Note that device_open_new is gated on defining
> DEVICE_ENABLE_DEVICE_OPEN_NEW because otherwise some hurd servers
> wouldn't compile anymore unless patched. This macro allows us to control
> the rollout.
> ---
>  device/ds_routines.c   |  8 
>  include/device/device.defs | 21 +
>  include/device/device_request.defs |  8 
>  include/device/device_types.defs   |  2 ++
>  4 files changed, 39 insertions(+)
> 
> diff --git a/device/ds_routines.c b/device/ds_routines.c
> index 94e61592..1f0bacf4 100644
> --- a/device/ds_routines.c
> +++ b/device/ds_routines.c
> @@ -170,6 +170,14 @@ ds_device_open (ipc_port_t open_port, ipc_port_t 
> reply_port,
>return err;
>  }
>  
> +io_return_t
> +ds_device_open_new (ipc_port_t open_port, ipc_port_t reply_port,
> + mach_msg_type_name_t reply_port_type, dev_mode_t mode,
> + const_dev_name_t name, device_t *devp)
> +{
> + return ds_device_open (open_port, reply_port, reply_port_type, mode, 
> name, devp);
> +}
> +
>  io_return_t
>  ds_device_close (device_t dev)
>  {
> diff --git a/include/device/device.defs b/include/device/device.defs
> index d1df799d..7f316129 100644
> --- a/include/device/device.defs
> +++ b/include/device/device.defs
> @@ -53,6 +53,7 @@ type reply_port_t = MACH_MSG_TYPE_MAKE_SEND_ONCE | 
> polymorphic
>  #endif   /* KERNEL_SERVER */
>  ;
>  
> +/* Deprecated in favor of device_open_new.  */
>  routine device_open(
>   master_port : mach_port_t;
>   sreplyport reply_port   : reply_port_t;
> @@ -110,7 +111,27 @@ routine  device_read_inband(
>   out data: io_buf_ptr_inband_t
>   );
>  
> +#if defined(KERNEL_SERVER) || defined(DEVICE_ENABLE_DEVICE_OPEN_NEW)
> +routine device_open_new(
> + master_port : mach_port_t;
> + sreplyport reply_port   : reply_port_t;
> + mode: dev_mode_t;
> + name: new_dev_name_t;
> + out device  : device_t =
> + MACH_MSG_TYPE_PORT_SEND
> + ctype: mach_port_t
> +#if  KERNEL_SERVER
> + outtran: mach_port_t convert_device_to_port(device_t)
> +#else
> +#ifdef   DEVICE_OUTTRAN
> + outtran: DEVICE_OUTTRAN
> +#endif
> +#endif   /* KERNEL_SERVER */
> + );
> +#else
>  skip;/* old xxx_device_set_status */
> +#endif
> +
>  skip;/* old xxx_device_get_status */
>  skip;/* old xxx_device_set_filter*/
>  
> diff --git a/include/device/device_request.defs 
> b/include/device/device_request.defs
> index 7ea8637c..a8af3a89 100644
> --- a/include/device/device_request.defs
> +++ b/include/device/device_request.defs
> @@ -45,6 +45,7 @@ type reply_port_t = MACH_MSG_TYPE_MAKE_SEND_ONCE
>  #endif   /* KERNEL_SERVER */
>  ;
>  
> +/* Deprecated in favor of device_open_new_request.  */
>  simpleroutine device_open_request(
>   device_server_port  : mach_port_t;
>ureplyport reply_port  : reply_port_t;
> @@ -85,3 +86,10 @@ simpleroutine device_read_request_inband(
>   in  recnum  : recnum_t;
>   in  bytes_wanted: int
>   );
> +
> +simpleroutine device_open_new_request(
> + device_server_port  : mach_port_t;
> +  ureplyport reply_port  : reply_port_t;
> + in  mode: dev_mode_t;
> + in  name: new_dev_name_t
> + );
> diff --git a/include/device/device_types.defs 
> b/include/device/device_types.defs
> index de8dbb02..c74bff51 100644
> --- a/include/device/device_types.defs
> +++ b/include/device/device_types.defs
> @@ -56,6 +56,8 @@ type recnum_t   = rpc_recnum_t
>  type dev_mode_t  = uint32_t;
>  type dev_flavor_t= uint32_t;
>  type dev_name_t  = (MACH_MSG_TYPE_STRING_C, 8*128);
> +type new_dev_name_t = c_string[128]
> + ctype: dev_name_t;
>  type dev_status_t= array[*:1024] of int;
>  type io_buf_ptr_t= ^array[] of MACH_MSG_TYPE_INTEGER_8;
>  type io_buf_ptr_inband_t= array[*:128] of char;
> -- 
> 2.39.2
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



[PATCH v3 1/6] hurd: Implement sigreturn for x86_64

2023-04-29 Thread Sergey Bugaev
Signed-off-by: Sergey Bugaev 
---
This incorporates back the fix made to the i386 version: we do need to call
_hurd_self_sigstate () once after all.

 sysdeps/mach/hurd/x86_64/sigreturn.c | 162 +++
 1 file changed, 162 insertions(+)
 create mode 100644 sysdeps/mach/hurd/x86_64/sigreturn.c

diff --git a/sysdeps/mach/hurd/x86_64/sigreturn.c 
b/sysdeps/mach/hurd/x86_64/sigreturn.c
new file mode 100644
index ..82247e3c
--- /dev/null
+++ b/sysdeps/mach/hurd/x86_64/sigreturn.c
@@ -0,0 +1,162 @@
+/* Copyright (C) 1991-2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   .  */
+
+#include 
+#include 
+#include 
+#include 
+
+/* This is run on the thread stack after restoring it, to be able to
+   unlock SS off sigstack.  */
+void
+__sigreturn2 (struct hurd_sigstate *ss, uintptr_t *usp,
+  struct sigcontext *scp)
+{
+  mach_port_t reply_port;
+  _hurd_sigstate_unlock (ss);
+
+  /* Destroy the MiG reply port used by the signal handler, and restore the
+ reply port in use by the thread when interrupted.
+
+ We cannot use the original reply port for our RPCs that we do here, since
+ we could unexpectedly receive/consume a reply message meant for the user
+ (in particular, msg_sig_post_reply), and also since we would deallocate
+ the port if *our* RPC fails, which we don't want to do since the user
+ still has the old name.  And so, temporarily set MACH_PORT_DEAD as our
+ reply name, and make sure destroying the port is the very last RPC we
+ do.  */
+  reply_port = THREAD_GETMEM (THREAD_SELF, reply_port);
+  THREAD_SETMEM (THREAD_SELF, reply_port, MACH_PORT_DEAD);
+  if (__glibc_likely (MACH_PORT_VALID (reply_port)))
+(void) __mach_port_mod_refs (__mach_task_self (), reply_port,
+ MACH_PORT_RIGHT_RECEIVE, -1);
+  THREAD_SETMEM (THREAD_SELF, reply_port, scp->sc_reply_port);
+
+  asm volatile (
+/* Point the stack to the register dump.  */
+"movq %0, %%rsp\n"
+/* Pop off the registers.  */
+"popq %%r8\n"
+"popq %%r9\n"
+"popq %%r10\n"
+"popq %%r11\n"
+"popq %%r12\n"
+"popq %%r13\n"
+"popq %%r14\n"
+"popq %%r15\n"
+"popq %%rdi\n"
+"popq %%rsi\n"
+"popq %%rbp\n"
+"popq %%rbx\n"
+"popq %%rdx\n"
+"popq %%rcx\n"
+"popq %%rax\n"
+"popfq\n"
+/* Restore %rip and %rsp with a single instruction.  */
+"retq $128" :
+: "rm" (usp));
+  __builtin_unreachable ();
+}
+
+int
+__sigreturn (struct sigcontext *scp)
+{
+  struct hurd_sigstate *ss;
+  struct hurd_userlink *link = (void *) &scp[1];
+
+  if (__glibc_unlikely (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK)))
+{
+  errno = EINVAL;
+  return -1;
+}
+
+  ss = _hurd_self_sigstate ();
+  _hurd_sigstate_lock (ss);
+
+  /* Remove the link on the `active resources' chain added by
+ _hurd_setup_sighandler.  Its purpose was to make sure
+ that we got called; now we have, it is done.  */
+  _hurd_userlink_unlink (link);
+
+  /* Restore the set of blocked signals, and the intr_port slot.  */
+  ss->blocked = scp->sc_mask;
+  ss->intr_port = scp->sc_intr_port;
+
+  /* Check for pending signals that were blocked by the old set.  */
+  if (_hurd_sigstate_pending (ss) & ~ss->blocked)
+{
+  /* There are pending signals that just became unblocked.  Wake up the
+signal thread to deliver them.  But first, squirrel away SCP where
+the signal thread will notice it if it runs another handler, and
+arrange to have us called over again in the new reality.  */
+  ss->context = scp;
+  _hurd_sigstate_unlock (ss);
+  __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
+  /* If a pending signal was handled, sig_post never returned.
+If it did return, the pending signal didn't run a handler;
+proceed as usual.  */
+  _hurd_sigstate_lock (ss);
+  ss->context = NULL;
+}
+
+  if (scp->sc_onstack)
+ss->sigaltstack.ss_flags &= ~SS_ONSTACK;

[PATCH v3 2/6] hurd: Implement longjmp for x86_64

2023-04-29 Thread Sergey Bugaev
Checked on x86_64-gnu.

Signed-off-by: Sergey Bugaev 
---
I have checked that setjmp/longjmp actually works sucessfully, with both
__longjmp and longjmp_chk. I have not been able to check w/ sigaltstack
because we don't yet have the proc server and signals.

Changes since v1:
- drop the separate non-PIC version, we can always use %rip-relative access
  on x86_64, and that's what the compiler generates anyway even with -fno-pic;
- use "cmpb $0, __libc_tls_initialized(%rip)" over
  "movb __libc_tls_initialized(%rip), %r10b; testb %r10b, %r10b" -- the former
  is what the compiler generates, so better be consistent.

 sysdeps/mach/hurd/x86_64/longjmp_chk.S | 118 +
 sysdeps/mach/hurd/x86_64/__longjmp.S   |  96 +
 2 files changed, 214 insertions(+)
 create mode 100644 sysdeps/mach/hurd/x86_64/longjmp_chk.S
 create mode 100644 sysdeps/mach/hurd/x86_64/__longjmp.S

diff --git a/sysdeps/mach/hurd/x86_64/longjmp_chk.S 
b/sysdeps/mach/hurd/x86_64/longjmp_chk.S
new file mode 100644
index ..935b8575
--- /dev/null
+++ b/sysdeps/mach/hurd/x86_64/longjmp_chk.S
@@ -0,0 +1,118 @@
+/* Checked longjmp support.  x86_64 Hurd version.
+   Copyright (C) 2001-2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   .  */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define SS_ONSTACK 1
+
+/* Don't restore shadow stack register if shadow stack isn't enabled.  */
+#if !SHSTK_ENABLED
+# undef SHADOW_STACK_POINTER_OFFSET
+#endif
+
+   .section .rodata.str1.1,"aMS",@progbits,1
+   .type   longjmp_msg,@object
+longjmp_msg:
+   .string "longjmp causes uninitialized stack frame"
+   .size   longjmp_msg, .-longjmp_msg
+
+
+# define CALL_FAIL sub $8, %RSP_LP;  \
+   cfi_remember_state;   \
+   cfi_def_cfa_offset(16);   \
+   lea longjmp_msg(%rip), %RDI_LP;   \
+   callHIDDEN_JUMPTARGET(__fortify_fail);\
+   nop;  \
+   cfi_restore_state
+
+/* Jump to the position specified by ENV, causing the
+   setjmp call there to return VAL, or 1 if VAL is 0.
+   void __longjmp (__jmp_buf env, int val).  */
+   .text
+ENTRY(longjmp_chk)
+   /* Restore registers.  */
+   mov (JB_RSP*8)(%rdi), %R8_LP
+   mov (JB_RBP*8)(%rdi),%R9_LP
+   mov (JB_PC*8)(%rdi), %RDX_LP
+#ifdef PTR_DEMANGLE
+   PTR_DEMANGLE (%R8_LP)
+   PTR_DEMANGLE (%R9_LP)
+   PTR_DEMANGLE (%RDX_LP)
+#endif
+
+#if !defined (SHARED) || IS_IN (rtld)
+   cmpb$0, __libc_tls_initialized(%rip)
+   jz  .Lok/* TLS not initialized yet */
+#endif
+
+   movq %fs:SIGSTATE_OFFSET, %R10_LP
+   testq %R10_LP, %R10_LP
+   jz  .Lok/* sigstate not initialized yet */
+
+   testl   $SS_ONSTACK, (HURD_SIGSTATE__SIGALTSTACK__OFFSET + 
SIGALTSTACK__SS_FLAGS__OFFSET)(%R10_LP)
+   jnz .Lonstack
+
+   /* We were on the main stack.  Jumping to a higher-address
+   frame is always allowed, otherwise it's not allowed.  */
+   cmp %R8_LP, %RSP_LP
+   jbe .Lok
+
+.Lfail:CALL_FAIL
+
+.Lonstack:
+   cmpq(HURD_SIGSTATE__SIGALTSTACK__OFFSET + 
SIGALTSTACK__SS_SP__OFFSET)(%R10_LP), %R8_LP
+   jb  .Loks   /* Jumping below the altstack, switch */
+
+   movq(HURD_SIGSTATE__SIGALTSTACK__OFFSET + 
SIGALTSTACK__SS_SP__OFFSET)(%R10_LP), %R11_LP
+   addq(HURD_SIGSTATE__SIGALTSTACK__OFFSET + 
SIGALTSTACK__SS_SIZE__OFFSET)(%R10_LP), %R11_LP
+   cmpq%R11_LP, %R8_LP
+   jb  .Lok/* Jumping inside the altstack, do not switch */
+
+   /* Jumping above the altstack, switch */
+
+.Loks:
+   andl$~(SS_ONSTACK), (HURD_SIGSTATE__SIGALTSTACK__OFFSET + 
SIGALTSTACK__SS_FLAGS__OFFSET)(%R10_LP)
+
+.Lok:
+   /* We add unwind information for the target here.  */
+   cfi_def_cfa(%rdi, 0)
+   cfi_register(%rsp,%r8)
+   cfi_register(%rbp,%r9)
+   cfi_register(%rip,%rdx)
+   cfi_

[PATCH v3 4/6] hurd: Add expected abilist files for x86_64

2023-04-29 Thread Sergey Bugaev
These were created by creating stub files, running 'make update-abi',
and reviewing the results.

Also, set baseline ABI to GLIBC_2.38, the (upcoming) first glibc
release to first have x86_64-gnu support.

Signed-off-by: Sergey Bugaev 
---

Changes compared to v2:
- __pthread_self is now in libc.so, not libpthread.so
(I'm still not sure why this move is being done, though)

 sysdeps/mach/hurd/x86_64/ld.abilist   |   17 +
 .../mach/hurd/x86_64/libBrokenLocale.abilist  |1 +
 sysdeps/mach/hurd/x86_64/libc.abilist | 2121 +
 .../hurd/x86_64/libc_malloc_debug.abilist |   26 +
 sysdeps/mach/hurd/x86_64/libcrypt.abilist |2 +
 sysdeps/mach/hurd/x86_64/libdl.abilist|0
 sysdeps/mach/hurd/x86_64/libm.abilist | 1040 
 sysdeps/mach/hurd/x86_64/libmvec.abilist  |  216 ++
 sysdeps/mach/hurd/x86_64/libpthread.abilist   |  175 ++
 sysdeps/mach/hurd/x86_64/libresolv.abilist|   55 +
 sysdeps/mach/hurd/x86_64/librt.abilist|   33 +
 sysdeps/mach/hurd/x86_64/shlib-versions   |1 +
 12 files changed, 3687 insertions(+)
 create mode 100644 sysdeps/mach/hurd/x86_64/ld.abilist
 create mode 100644 sysdeps/mach/hurd/x86_64/libBrokenLocale.abilist
 create mode 100644 sysdeps/mach/hurd/x86_64/libc.abilist
 create mode 100644 sysdeps/mach/hurd/x86_64/libc_malloc_debug.abilist
 create mode 100644 sysdeps/mach/hurd/x86_64/libcrypt.abilist
 create mode 100644 sysdeps/mach/hurd/x86_64/libdl.abilist
 create mode 100644 sysdeps/mach/hurd/x86_64/libm.abilist
 create mode 100644 sysdeps/mach/hurd/x86_64/libmvec.abilist
 create mode 100644 sysdeps/mach/hurd/x86_64/libpthread.abilist
 create mode 100644 sysdeps/mach/hurd/x86_64/libresolv.abilist
 create mode 100644 sysdeps/mach/hurd/x86_64/librt.abilist
 create mode 100644 sysdeps/mach/hurd/x86_64/shlib-versions

diff --git a/sysdeps/mach/hurd/x86_64/ld.abilist 
b/sysdeps/mach/hurd/x86_64/ld.abilist
new file mode 100644
index ..2297a5f3
--- /dev/null
+++ b/sysdeps/mach/hurd/x86_64/ld.abilist
@@ -0,0 +1,17 @@
+GLIBC_2.38 __close F
+GLIBC_2.38 __errno_location F
+GLIBC_2.38 __getpid F
+GLIBC_2.38 __libc_stack_end D 0x8
+GLIBC_2.38 __mmap F
+GLIBC_2.38 __open F
+GLIBC_2.38 __open64 F
+GLIBC_2.38 __pread64 F
+GLIBC_2.38 __read F
+GLIBC_2.38 __sbrk F
+GLIBC_2.38 __tls_get_addr F
+GLIBC_2.38 __write F
+GLIBC_2.38 __writev F
+GLIBC_2.38 _dl_mcount F
+GLIBC_2.38 _hurd_intr_rpc_mach_msg F
+GLIBC_2.38 _r_debug D 0x28
+GLIBC_2.38 abort F
diff --git a/sysdeps/mach/hurd/x86_64/libBrokenLocale.abilist 
b/sysdeps/mach/hurd/x86_64/libBrokenLocale.abilist
new file mode 100644
index ..203836f5
--- /dev/null
+++ b/sysdeps/mach/hurd/x86_64/libBrokenLocale.abilist
@@ -0,0 +1 @@
+GLIBC_2.38 __ctype_get_mb_cur_max F
diff --git a/sysdeps/mach/hurd/x86_64/libc.abilist 
b/sysdeps/mach/hurd/x86_64/libc.abilist
new file mode 100644
index ..cafdd8a0
--- /dev/null
+++ b/sysdeps/mach/hurd/x86_64/libc.abilist
@@ -0,0 +1,2121 @@
+GLIBC_2.38 _Exit F
+GLIBC_2.38 _Fork F
+GLIBC_2.38 _IO_2_1_stderr_ D 0xe0
+GLIBC_2.38 _IO_2_1_stdin_ D 0xe0
+GLIBC_2.38 _IO_2_1_stdout_ D 0xe0
+GLIBC_2.38 _IO_adjust_column F
+GLIBC_2.38 _IO_adjust_wcolumn F
+GLIBC_2.38 _IO_default_doallocate F
+GLIBC_2.38 _IO_default_finish F
+GLIBC_2.38 _IO_default_pbackfail F
+GLIBC_2.38 _IO_default_uflow F
+GLIBC_2.38 _IO_default_xsgetn F
+GLIBC_2.38 _IO_default_xsputn F
+GLIBC_2.38 _IO_do_write F
+GLIBC_2.38 _IO_doallocbuf F
+GLIBC_2.38 _IO_fclose F
+GLIBC_2.38 _IO_fdopen F
+GLIBC_2.38 _IO_feof F
+GLIBC_2.38 _IO_ferror F
+GLIBC_2.38 _IO_fflush F
+GLIBC_2.38 _IO_fgetpos F
+GLIBC_2.38 _IO_fgetpos64 F
+GLIBC_2.38 _IO_fgets F
+GLIBC_2.38 _IO_file_attach F
+GLIBC_2.38 _IO_file_close F
+GLIBC_2.38 _IO_file_close_it F
+GLIBC_2.38 _IO_file_doallocate F
+GLIBC_2.38 _IO_file_finish F
+GLIBC_2.38 _IO_file_fopen F
+GLIBC_2.38 _IO_file_init F
+GLIBC_2.38 _IO_file_jumps D 0xa8
+GLIBC_2.38 _IO_file_open F
+GLIBC_2.38 _IO_file_overflow F
+GLIBC_2.38 _IO_file_read F
+GLIBC_2.38 _IO_file_seek F
+GLIBC_2.38 _IO_file_seekoff F
+GLIBC_2.38 _IO_file_setbuf F
+GLIBC_2.38 _IO_file_stat F
+GLIBC_2.38 _IO_file_sync F
+GLIBC_2.38 _IO_file_underflow F
+GLIBC_2.38 _IO_file_write F
+GLIBC_2.38 _IO_file_xsputn F
+GLIBC_2.38 _IO_flockfile F
+GLIBC_2.38 _IO_flush_all F
+GLIBC_2.38 _IO_flush_all_linebuffered F
+GLIBC_2.38 _IO_fopen F
+GLIBC_2.38 _IO_fprintf F
+GLIBC_2.38 _IO_fputs F
+GLIBC_2.38 _IO_fread F
+GLIBC_2.38 _IO_free_backup_area F
+GLIBC_2.38 _IO_free_wbackup_area F
+GLIBC_2.38 _IO_fsetpos F
+GLIBC_2.38 _IO_fsetpos64 F
+GLIBC_2.38 _IO_ftell F
+GLIBC_2.38 _IO_ftrylockfile F
+GLIBC_2.38 _IO_funlockfile F
+GLIBC_2.38 _IO_fwrite F
+GLIBC_2.38 _IO_getc F
+GLIBC_2.38 _IO_getline F
+GLIBC_2.38 _IO_getline_info F
+GLIBC_2.38 _IO_gets F
+GLIBC_2.38 _IO_init F
+GLIBC_2.38 _IO_init_marker F
+GLIBC_2.38 _IO_init_wmarker F
+GLIBC_2.38 _IO_iter_begin F
+GLIBC_2.38 _IO_iter_end F
+GLIBC_2.38 _IO_iter_file F
+GLIBC_2.38 _IO_iter_next F
+GLIBC_2.38 _IO_least_wmarker F
+GLIBC_2.38 _IO_l

[RFC PATCH v3 3/6] hurd: Replace reply port with a dead name on failed interruption

2023-04-29 Thread Sergey Bugaev
If we're trying to interrupt an interruptible RPC, but the server fails
to respond to our __interrupt_operation () call, we instead destroy the
reply port we were expecting the reply to the RPC on.

Instead of deallocating the name completely, replace it with a dead
name, so the name won't get reused for some other right, and deallocate
it in _hurd_intr_rpc_mach_msg once we return from the signal handler.

Signed-off-by: Sergey Bugaev 
---
This is not required for x86_64, but probably a good idea anyway. I have
checked that this does not fatally break things (this commit has been
sitting in my tree, getting built along with the other changes, for quite
some time without noticably breaking anything), but I have not run the
full testsuite. Please do that on your end.

 hurd/hurdsig.c| 15 ---
 hurd/intr-msg.c   |  1 +
 sysdeps/mach/hurd/mig-reply.c | 25 +++--
 3 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
index b3808f9e..78ea59d9 100644
--- a/hurd/hurdsig.c
+++ b/hurd/hurdsig.c
@@ -477,9 +477,18 @@ _hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, 
int sigthread,
   if (reply)
 {
   /* The interrupt didn't work.
- Destroy the receive right the thread is blocked on.  */
-  __mach_port_destroy (__mach_task_self (), *reply);
-  *reply = MACH_PORT_NULL;
+ Destroy the receive right the thread is blocked on, and
+ replace it with a dead name to keep the name from reuse until
+ the therad is done with it.  To do this atomically, first
+ insert a send right, and then destroy the receive right,
+ turning the send right into a dead name.  */
+  err = __mach_port_insert_right (__mach_task_self (),
+  *reply, *reply,
+  MACH_MSG_TYPE_MAKE_SEND);
+  assert_perror (err);
+  err = __mach_port_mod_refs (__mach_task_self (), *reply,
+  MACH_PORT_RIGHT_RECEIVE, -1);
+  assert_perror (err);
 }
 
   /* The system call return value register now contains
diff --git a/hurd/intr-msg.c b/hurd/intr-msg.c
index 1a086b51..716d87ab 100644
--- a/hurd/intr-msg.c
+++ b/hurd/intr-msg.c
@@ -305,6 +305,7 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
{
  /* Make sure we have a valid reply port.  The one we were using
 may have been destroyed by interruption.  */
+ __mig_dealloc_reply_port (rcv_name);
  m->header.msgh_local_port = rcv_name = __mig_get_reply_port ();
  m->header.msgh_bits = msgh_bits;
  option = user_option;
diff --git a/sysdeps/mach/hurd/mig-reply.c b/sysdeps/mach/hurd/mig-reply.c
index 3fdee80e..7ea001df 100644
--- a/sysdeps/mach/hurd/mig-reply.c
+++ b/sysdeps/mach/hurd/mig-reply.c
@@ -69,29 +69,18 @@ __mig_dealloc_reply_port (mach_port_t arg)
   mach_port_t port = get_reply_port ();
 
   set_reply_port (MACH_PORT_NULL); /* So the mod_refs RPC won't use it.  */
-
-  /* Normally, ARG should be the same as PORT that we store.  However, if a
- signal has interrupted the RPC, the stored PORT has been deallocated and
- reset to MACH_PORT_NULL (or possibly MACH_PORT_DEAD).  In this case the
- MIG routine still has the old name, which it passes to us here.  We must
- not deallocate (or otherwise touch) it, since it may be already allocated
- to another port right.  Fortunately MIG itself doesn't do anything with
- the reply port on errors either, other than immediately calling this
- function.
-
- And so:
- 1. Assert that things are sane, i.e. and PORT is either invalid or same
-as ARG.
- 2. Only deallocate the name if our stored PORT still names it.  In that
-case we're sure the right has not been deallocated / the name reused.
-*/
-
+  assert (port == arg);
   if (!MACH_PORT_VALID (port))
 return;
-  assert (port == arg);
 
   err = __mach_port_mod_refs (__mach_task_self (), port,
   MACH_PORT_RIGHT_RECEIVE, -1);
+  if (err == KERN_INVALID_RIGHT)
+/* It could be that during signal handling, the receive right had been
+   replaced with a dead name.  */
+err = __mach_port_mod_refs (__mach_task_self (), port,
+MACH_PORT_RIGHT_DEAD_NAME, -1);
+
   assert_perror (err);
 }
 weak_alias (__mig_dealloc_reply_port, mig_dealloc_reply_port)
-- 
2.40.1




[RFC PATCH v3 5/6] hurd: Make it possible to call memcpy very early

2023-04-29 Thread Sergey Bugaev
Normally, in static builds, the first code that runs is _start, in e.g.
sysdeps/x86_64/start.S, which quickly calls __libc_start_main, passing
it the argv etc. Among the first things __libc_start_main does is
initializing the tunables (based on env), then CPU features, and then
calls _dl_relocate_static_pie (). Specifically, this runs ifunc
resolvers to pick, based on the CPU features discovered earlier, the
most suitable implementation of "string" functions such as memcpy.

Before that point, calling memcpy (or other ifunc-resolved functions)
will not work.

In the Hurd port, things are more complex. In order to get argv/env for
our process, glibc normally needs to do an RPC to the exec server,
unless our args/env are already located on the stack (which is what
happens to bootstrap processes spawned by GNU Mach). Fetching our
argv/env from the exec server has to be done before the call to
__libc_start_main, since we need to know what our argv/env are to pass
them to __libc_start_main.

On the other hand, the implementation of the RPC (and other initial
setup needed on the Hurd before __libc_start_main can be run) is not
very trivial. In particular, it may (and on x86_64, will) use memcpy.
But as described above, calling memcpy before __libc_start_main can not
work, since the GOT entry for it is not yet initialized at that point.

Work around this by pre-filling the GOT entry with the baseline version
of memcpy, __memcpy_sse2_unaligned. This makes it possible for early
calls to memcpy to just work. The initial value of the GOT entry is
unused on x86_64, and changing it won't interfere with the relocation
being performed later: once _dl_relocate_static_pie () is called, the
baseline version will get replaced with the most suitable one, and that
is what subsequent calls of memcpy are going to call.

Checked on x86_64-gnu.

Signed-off-by: Sergey Bugaev 
---
Changes since v1:
- drop the stpncpy, since it's apparently not required during early
  startup;
- as a result of the above, there are no longer any changes to the
  i386 version;
- drop the PIC/non-PIC split, we can always use %rip-relative addressing
  on x86_64;
- as mentioned somewhere in the v1 thread, I have, since posting the v1,
  actually gone and checked that the relocations do work and the proper,
  more effecient memcpy version does get installed into the GOT slot and
  invoked whenever anything calls memcpy;
- convinced myself that this is not a terrible hack but rather an OK
  solution;
- worked out how this would be done on an architecture that (like i386,
  unlike x86_64) does need the original value in the GOT to perform the
  relocation, but (unlike i386, like x86_64) still uses an ifunc-selected
  memcpy in static builds: namely, we'd simply put the original ifunc
  address back into the GOT slot a few lines below, after the call to
  _hurd_stack_setup.

 sysdeps/mach/hurd/x86_64/static-start.S | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/sysdeps/mach/hurd/x86_64/static-start.S 
b/sysdeps/mach/hurd/x86_64/static-start.S
index 982d3d52..cc8e2410 100644
--- a/sysdeps/mach/hurd/x86_64/static-start.S
+++ b/sysdeps/mach/hurd/x86_64/static-start.S
@@ -19,6 +19,9 @@
.text
.globl _start
 _start:
+
+   leaq __memcpy_sse2_unaligned(%rip), %rax
+   movq %rax, memcpy@GOTPCREL(%rip)
call _hurd_stack_setup
xorq %rdx, %rdx
jmp _start1
-- 
2.40.1




[PATCH v3 0/6] The remaining x86_64-gnu patches

2023-04-29 Thread Sergey Bugaev
These are the patches that I have locally that have not (yet) been
pushed. Most of them I have already sent previously, but have made
changes to since then. Please see the notes on individual patches.

I'm putting "v3" on the whole series because some of the patches here
have already been through v1 and v2.

If these patches are pushed, it should be possible for anyone to build
x86_64-gnu glibc just out of Git master, without having to dig through
the mailing list archive for uncommited patches.

Sergey



[DO NOT PUSH PATCH v3 6/6] TMP hurd: Lower BRK_START

2023-04-29 Thread Sergey Bugaev
...until gnumach learns to support higher addresses
---
This is not meant to be pushed, but you're going to need this patch
to run glibc on the current builds of gnumach.

 sysdeps/mach/hurd/x86_64/vm_param.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sysdeps/mach/hurd/x86_64/vm_param.h 
b/sysdeps/mach/hurd/x86_64/vm_param.h
index f269afb3..e35596bd 100644
--- a/sysdeps/mach/hurd/x86_64/vm_param.h
+++ b/sysdeps/mach/hurd/x86_64/vm_param.h
@@ -19,6 +19,7 @@
 #define _X86_64_VM_PARAM_H
 
 /* Arbitrary start of the brk. This is after usual binary and library 
mappings.  */
-#define BRK_START  0x2000
+// #define BRK_START   0x2000
+#define BRK_START  0x2000
 
 #endif /* x86_64/vm_param.h */
-- 
2.40.1




[PATCH] Define mig_strlen and __mig_strlen to support dynamically sized strings in hurd RPCs

2023-04-29 Thread Flavio Cruz
We make lib{mach,hurd}user.so call __mig_strlen which can be
relocated before libc.so is relocated, similar to what is done with
__mig_memcpy.
---
 mach/Makefile   |  2 +-
 mach/Versions   |  4 
 mach/mach/mig_support.h |  2 ++
 mach/mig_strlen.c   | 27 +++
 sysdeps/mach/hurd/i386/libc.abilist |  1 +
 5 files changed, 35 insertions(+), 1 deletion(-)
 create mode 100644 mach/mig_strlen.c

diff --git a/mach/Makefile b/mach/Makefile
index 39358fdb83..a5d1252f95 100644
--- a/mach/Makefile
+++ b/mach/Makefile
@@ -25,7 +25,7 @@ headers = mach_init.h mach.h mach_error.h mach-shortcuts.h 
mach/mach_traps.h \
 lock = spin-solid spin-lock mutex-init mutex-solid
 lock-headers = lock-intern.h spin-lock.h
 routines = $(mach-syscalls) $(mach-shortcuts) \
-  mach_init mig_strncpy mig_memcpy msg \
+  mach_init mig_strncpy mig_strlen mig_memcpy msg \
   mig-alloc mig-dealloc mig-reply \
   msg-destroy msgserver \
   mach_error errstring error_compat errsystems \
diff --git a/mach/Versions b/mach/Versions
index b525cfdcf9..2dff5c477e 100644
--- a/mach/Versions
+++ b/mach/Versions
@@ -61,6 +61,9 @@ libc {
   GLIBC_2.32 {
 mach_print;
   }
+  GLIBC_2.38 {
+mig_strlen;
+  }
 
   HURD_CTHREADS_0.3 {
 __mutex_init; __mutex_lock; __mutex_lock_solid; __mutex_trylock;
@@ -71,5 +74,6 @@ libc {
   GLIBC_PRIVATE {
 # functions used by RPC stubs
 __mig_memcpy;
+__mig_strlen;
   }
 }
diff --git a/mach/mach/mig_support.h b/mach/mach/mig_support.h
index 78d4c4f0e3..3108e0af56 100644
--- a/mach/mach/mig_support.h
+++ b/mach/mach/mig_support.h
@@ -53,6 +53,8 @@ extern void mig_reply_setup (const mach_msg_header_t 
*__request,
 /* Idiocy support function.  */
 extern vm_size_t mig_strncpy (char *__dst, const char *__src, vm_size_t __len);
 extern vm_size_t __mig_strncpy (char *__dst, const char *__src, vm_size_t);
+extern vm_size_t mig_strlen (const char *__src);
+extern vm_size_t __mig_strlen (const char *__src);
 
 extern void *__mig_memcpy (void *__dst, const void *__src, vm_size_t __len);
 
diff --git a/mach/mig_strlen.c b/mach/mig_strlen.c
new file mode 100644
index 00..65e39b9bdf
--- /dev/null
+++ b/mach/mig_strlen.c
@@ -0,0 +1,27 @@
+/* strlen stub for mig stubs in libmachuser and libhurduser.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   .  */
+
+#include 
+#include 
+
+vm_size_t
+__mig_strlen (const char *src)
+{
+  return strlen (src);
+}
+weak_alias (__mig_strlen, mig_strlen)
diff --git a/sysdeps/mach/hurd/i386/libc.abilist 
b/sysdeps/mach/hurd/i386/libc.abilist
index 6925222ff3..ac7d06e385 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2326,6 +2326,7 @@ GLIBC_2.38 __isoc23_wcstoull F
 GLIBC_2.38 __isoc23_wcstoull_l F
 GLIBC_2.38 __isoc23_wcstoumax F
 GLIBC_2.38 __isoc23_wscanf F
+GLIBC_2.38 mig_strlen F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
-- 
2.39.2




[PATCH] Make __mach_msg_destroy portable for x86_64

2023-04-29 Thread Flavio Cruz
We need to align on uintptr_t to make this work for x86_64, 
otherwise things will go wrong when RPCs return errors.
---
 mach/msg-destroy.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/mach/msg-destroy.c b/mach/msg-destroy.c
index 7429ecbc2d..0a8b46c895 100644
--- a/mach/msg-destroy.c
+++ b/mach/msg-destroy.c
@@ -38,6 +38,7 @@
  *
  */
 
+#include 
 #if 1
 #include 
 #else
@@ -162,9 +163,10 @@ __mach_msg_destroy (mach_msg_header_t *msg)
saddr += sizeof(mach_msg_type_t);
}
 
-   /* calculate length of data in bytes, rounding up */
-   length = (number * size) + 7) >> 3) + sizeof (int) - 1)
- &~ (sizeof (int) - 1));
+   /* Calculate length of data in bytes... */
+   length = ((number * size) + 7) >> 3;
+   /* ... and round up using uintptr_t alignment */
+   length = ALIGN_UP (length, __alignof__ (uintptr_t));
 
addr = is_inline ? saddr : * (vm_offset_t *) saddr;
 
@@ -177,7 +179,6 @@ __mach_msg_destroy (mach_msg_header_t *msg)
}
 
if (is_inline) {
-   /* inline data sizes round up to int boundaries */
saddr += length;
} else {
mach_msg_destroy_memory(addr, length);
-- 
2.39.2