[PATCH v2 hurd] MAKEDEV: when creating devices, ensure the underlying files are either block/char devices or directories

2024-03-05 Thread Flavio Cruz
The perl test suite has a test where it reads all the block or char devices
under /dev without following the translators. Then it compares it against a
list of devices that read the translated nodes stat info.

The patch changes how the the device files are created initially so that the 
stat information
is identical and makes the Hurd environment appear more similar to other 
operating
systems.
---
 sutils/MAKEDEV.sh | 64 +--
 1 file changed, 39 insertions(+), 25 deletions(-)

diff --git a/sutils/MAKEDEV.sh b/sutils/MAKEDEV.sh
index 0702663..c3d7d11 100644
--- a/sutils/MAKEDEV.sh
+++ b/sutils/MAKEDEV.sh
@@ -77,10 +77,24 @@ st() {
   local NODE="$1"
   local OWNER="$2"
   local PERM="$3"
-  shift 3
+  local NODE_TYPE="$4"
+  shift 4
   if [ "$KEEP" ] && showtrans "$NODE" > /dev/null 2>&1 ; then
 return;
   fi
+  if [ ! -e "$NODE" ]; then
+case "$NODE_TYPE" in
+  b|c)
+cmd mknod "$NODE" "$NODE_TYPE" 0 0
+;;
+  d)
+cmd mkdir "$NODE"
+;;
+  *)
+lose "Unknown node type $NODE_TYPE for $NODE"
+;;
+esac
+  fi
   if cmd settrans $STFLAGS -c "$NODE"; then
 cmd chown "$OWNER" "$NODE"
 cmd chmod "$PERM" "$NODE"
@@ -109,47 +123,47 @@ mkdev() {
mkdev console tty random urandom null zero full fd time mem klog shm
;;
   console|com[0-9])
-   st $I root 600 /hurd/term ${DEVDIR}/$I device $I;;
+   st $I root 600 c /hurd/term ${DEVDIR}/$I device $I;;
   vcs)
-st $I root 600 /hurd/console;;
+st $I root 600 d /hurd/console;;
   tty[1-9][0-9]|tty[1-9])
-st $I root 600 /hurd/term ${DEVDIR}/$I hurdio \
+st $I root 600 c /hurd/term ${DEVDIR}/$I hurdio \
   ${DEVDIR}/vcs/`echo $I | sed -e s/tty//`/console;;
   lpr[0-9])
-st $I root 660 /hurd/streamio "$I";;
+st $I root 660 c /hurd/streamio "$I";;
   random)
-   st $I root 644 /hurd/random --seed-file /var/lib/random-seed;;
+   st $I root 644 c /hurd/random --seed-file /var/lib/random-seed;;
   urandom)
# Our /dev/random is both secure and non-blocking.  Create a
# link for compatibility with Linux.
cmd ln -f -s random $I;;
   null)
-   st $I root 666 /hurd/null;;
+   st $I root 666 c /hurd/null;;
   full)
-   st $I root 666 /hurd/null --full;;
+   st $I root 666 c /hurd/null --full;;
   zero)
-   st $I root 666 /bin/nullauth -- /hurd/storeio -Tzero;;
+   st $I root 666 c /bin/nullauth -- /hurd/storeio -Tzero;;
   tty)
-   st $I root 666 /hurd/magic tty;;
+   st $I root 666 c /hurd/magic tty;;
   fd)
-   st $I root 666 /hurd/magic --directory fd
+   st $I root 666 d /hurd/magic --directory fd
cmd ln -f -s fd/0 stdin
cmd ln -f -s fd/1 stdout
cmd ln -f -s fd/2 stderr
;;
   'time')
-   st $I root 644 /hurd/storeio --no-cache time ;;
+   st $I root 644 c /hurd/storeio --no-cache time ;;
   mem)
-   st $I root 660 /hurd/storeio --no-cache mem ;;
+   st $I root 660 c /hurd/storeio --no-cache mem ;;
   klog)
-st $I root 660 /hurd/streamio kmsg;;
+st $I root 660 c /hurd/streamio kmsg;;
   # ptys
   [pt]ty[pqrstuvwxyzPQRS]?)
# Make one pty, both the master and slave halves.
local id="${I#???}"
-   st pty$id root 666 /hurd/term ${DEVDIR}/pty$id \
+   st pty$id root 666 c /hurd/term ${DEVDIR}/pty$id \
  pty-master ${DEVDIR}/tty$id
-   st tty$id root 666 /hurd/term ${DEVDIR}/tty$id \
+   st tty$id root 666 c /hurd/term ${DEVDIR}/tty$id \
  pty-slave ${DEVDIR}/pty$id
;;
   [pt]ty[pqrstuvwxyzPQRS])
@@ -162,11 +176,11 @@ mkdev() {
;;
 
   fd*|mt*)
-   st $I root 640 /hurd/storeio $I
+   st $I root 640 b /hurd/storeio $I
;;
 
   rumpdisk)
-   st $I root 660 /hurd/rumpdisk
+   st $I root 660 c /hurd/rumpdisk
cmd ln -f -s rumpdisk disk
;;
   [hrscw]d*)
@@ -214,18 +228,18 @@ mkdev() {
# The device name passed all syntax checks, so finally use it!
if [ "$USE_PARTSTORE" ] && [ -z "$rest" ] && [ "$sliceno" ]; then
  local dev=${I%s[0-9]*}
- st $I root 640 /hurd/storeio -T typed part:$sliceno:device:$MASTER$dev
+ st $I root 640 b /hurd/storeio -T typed 
part:$sliceno:device:$MASTER$dev
else
- st $I root 640 /hurd/storeio $MASTER$I
+ st $I root 640 b /hurd/storeio $MASTER$I
fi
;;
 
   netdde)
-   st $I root 660 /hurd/netdde
+   st $I root 660 c /hurd/netdde
cmd ln -f -s netdde net
;;
   eth*)
-   st $I root 660 /hurd/devnode -M /dev/net $I;;
+   st $I root 660 c /hurd/devnode -M /dev/net $I;;
 
   # /dev/shm is used by the POSIX.1 shm_open call in libc.
   # We don't want the underlying node to be written by 

[PATCH hurd] MAKEDEV: when creating devices, ensure the underlying files are either block/char devices or directories

2024-03-04 Thread Flavio Cruz
The perl test suite has a test where it reads all the block or char devices
under /dev without following the translators. Then it compares it against a
list of devices that read the translated nodes stat info.

The patch changes how the the device files are created initially so that the 
stat information
is identical and makes the Hurd environment appear more similar to other 
operating
systems.
---
 sutils/MAKEDEV.sh | 67 +++
 1 file changed, 44 insertions(+), 23 deletions(-)

diff --git a/sutils/MAKEDEV.sh b/sutils/MAKEDEV.sh
index 0702663..79757fc 100644
--- a/sutils/MAKEDEV.sh
+++ b/sutils/MAKEDEV.sh
@@ -81,6 +81,27 @@ st() {
   if [ "$KEEP" ] && showtrans "$NODE" > /dev/null 2>&1 ; then
 return;
   fi
+  local NODE_TYPE="$1"
+  case "$NODE_TYPE" in
+b|c|d|f)
+  shift 1
+  ;;
+*)
+  NODE_TYPE="f"
+  ;;
+  esac
+  if [ ! -e "$NODE" ]; then
+case "$NODE_TYPE" in
+  b|c)
+cmd mknod "$NODE" "$NODE_TYPE" 0 0
+;;
+  d)
+cmd mkdir "$NODE"
+;;
+  *)
+;;
+esac
+  fi
   if cmd settrans $STFLAGS -c "$NODE"; then
 cmd chown "$OWNER" "$NODE"
 cmd chmod "$PERM" "$NODE"
@@ -109,47 +130,47 @@ mkdev() {
mkdev console tty random urandom null zero full fd time mem klog shm
;;
   console|com[0-9])
-   st $I root 600 /hurd/term ${DEVDIR}/$I device $I;;
+   st $I root 600 c /hurd/term ${DEVDIR}/$I device $I;;
   vcs)
-st $I root 600 /hurd/console;;
+st $I root 600 d /hurd/console;;
   tty[1-9][0-9]|tty[1-9])
-st $I root 600 /hurd/term ${DEVDIR}/$I hurdio \
+st $I root 600 c /hurd/term ${DEVDIR}/$I hurdio \
   ${DEVDIR}/vcs/`echo $I | sed -e s/tty//`/console;;
   lpr[0-9])
-st $I root 660 /hurd/streamio "$I";;
+st $I root 660 c /hurd/streamio "$I";;
   random)
-   st $I root 644 /hurd/random --seed-file /var/lib/random-seed;;
+   st $I root 644 c /hurd/random --seed-file /var/lib/random-seed;;
   urandom)
# Our /dev/random is both secure and non-blocking.  Create a
# link for compatibility with Linux.
cmd ln -f -s random $I;;
   null)
-   st $I root 666 /hurd/null;;
+   st $I root 666 c /hurd/null;;
   full)
-   st $I root 666 /hurd/null --full;;
+   st $I root 666 c /hurd/null --full;;
   zero)
-   st $I root 666 /bin/nullauth -- /hurd/storeio -Tzero;;
+   st $I root 666 c /bin/nullauth -- /hurd/storeio -Tzero;;
   tty)
-   st $I root 666 /hurd/magic tty;;
+   st $I root 666 c /hurd/magic tty;;
   fd)
-   st $I root 666 /hurd/magic --directory fd
+   st $I root 666 d /hurd/magic --directory fd
cmd ln -f -s fd/0 stdin
cmd ln -f -s fd/1 stdout
cmd ln -f -s fd/2 stderr
;;
   'time')
-   st $I root 644 /hurd/storeio --no-cache time ;;
+   st $I root 644 c /hurd/storeio --no-cache time ;;
   mem)
-   st $I root 660 /hurd/storeio --no-cache mem ;;
+   st $I root 660 c /hurd/storeio --no-cache mem ;;
   klog)
-st $I root 660 /hurd/streamio kmsg;;
+st $I root 660 c /hurd/streamio kmsg;;
   # ptys
   [pt]ty[pqrstuvwxyzPQRS]?)
# Make one pty, both the master and slave halves.
local id="${I#???}"
-   st pty$id root 666 /hurd/term ${DEVDIR}/pty$id \
+   st pty$id root 666 c /hurd/term ${DEVDIR}/pty$id \
  pty-master ${DEVDIR}/tty$id
-   st tty$id root 666 /hurd/term ${DEVDIR}/tty$id \
+   st tty$id root 666 c /hurd/term ${DEVDIR}/tty$id \
  pty-slave ${DEVDIR}/pty$id
;;
   [pt]ty[pqrstuvwxyzPQRS])
@@ -162,11 +183,11 @@ mkdev() {
;;
 
   fd*|mt*)
-   st $I root 640 /hurd/storeio $I
+   st $I root 640 b /hurd/storeio $I
;;
 
   rumpdisk)
-   st $I root 660 /hurd/rumpdisk
+   st $I root 660 c /hurd/rumpdisk
cmd ln -f -s rumpdisk disk
;;
   [hrscw]d*)
@@ -214,18 +235,18 @@ mkdev() {
# The device name passed all syntax checks, so finally use it!
if [ "$USE_PARTSTORE" ] && [ -z "$rest" ] && [ "$sliceno" ]; then
  local dev=${I%s[0-9]*}
- st $I root 640 /hurd/storeio -T typed part:$sliceno:device:$MASTER$dev
+ st $I root 640 b /hurd/storeio -T typed 
part:$sliceno:device:$MASTER$dev
else
- st $I root 640 /hurd/storeio $MASTER$I
+ st $I root 640 b /hurd/storeio $MASTER$I
fi
;;
 
   netdde)
-   st $I root 660 /hurd/netdde
+   st $I root 660 c /hurd/netdde
cmd ln -f -s netdde net
;;
   eth*)
-   st $I root 660 /hurd/devnode -M /dev/net $I;;
+   st $I root 660 c /hurd/devnode -M /dev/net $I;;
 
   # /dev/shm is used by the POSIX.1 shm_open call in libc.
   # We don't want the underlying node to be written by randoms,
@@ -235,7 +256,7 

[PATCH hurd] libps: update ps_emit_nice_size_t to handle arbitrarily large size_t

2024-03-03 Thread Flavio Cruz
Update argument types for sprint_frac_value to reflect how big they
actually are so that GCC doesn't think it needs a larger buffer than
necessary.
---
 libps/spec.c | 22 +-
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/libps/spec.c b/libps/spec.c
index 9f64703..60ae7fb 100644
--- a/libps/spec.c
+++ b/libps/spec.c
@@ -19,6 +19,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -437,12 +438,12 @@ ps_emit_num_blocks (struct proc_stat *ps, struct 
ps_fmt_field *field,
 
 size_t
 sprint_frac_value (char *buf,
- size_t value, int min_value_len,
- size_t frac, int frac_scale,
- int width)
+ uint16_t value, uint8_t min_value_len,
+ uint16_t frac, uint8_t frac_scale,
+ uint8_t width)
 {
-  int value_len = 0;
-  int frac_len = 0;
+  uint8_t value_len = 0;
+  uint8_t frac_len = 0;
 
   if (value >= 1000)/* the integer part */
 value_len = 4;  /* values 1000-1023 */
@@ -462,9 +463,9 @@ sprint_frac_value (char *buf,
 frac /= 10;
 
   if (frac_len > 0)
-sprintf (buf, "%zd.%0*zd", value, frac_len, frac);
+sprintf (buf, "%" PRIu16 ".%0*" PRIu16, value, frac_len, frac);
   else
-sprintf (buf, "%zd", value);
+sprintf (buf, "%" PRIu16, value);
 
   return strlen (buf);
 }
@@ -492,11 +493,14 @@ error_t
 ps_emit_nice_size_t (struct proc_stat *ps, struct ps_fmt_field *field,
 struct ps_stream *stream)
 {
-  char buf[21];
+  char buf[20];
   size_t value = FG_PROC_STAT (field, size_t)(ps);
-  char *sfx = " KMG";
+  char *sfx = " KMGTPE";
   size_t frac = 0;
 
+  _Static_assert (sizeof (size_t) <= 8,
+  "ps_emit_nice_size_t can only emit size_t up to 8 bytes long.");
+
   while (value >= 1024)
 {
   frac = ((value & 0x3FF) * 1000) >> 10;
-- 
2.39.2




[PATCH gcc] Hurd x86_64: add unwind support for signal trampoline code

2024-02-28 Thread Flavio Cruz
Tested with some simple toy examples where an exception is thrown in the
signal handler.

libgcc/ChangeLog:
* config/i386/gnu-unwind.h: Support unwinding x86_64 signal frames.

Signed-off-by: Flavio Cruz 
---
 libgcc/config/i386/gnu-unwind.h | 97 -
 1 file changed, 94 insertions(+), 3 deletions(-)

diff --git a/libgcc/config/i386/gnu-unwind.h b/libgcc/config/i386/gnu-unwind.h
index 0751b5593d4..02b060ab4a5 100644
--- a/libgcc/config/i386/gnu-unwind.h
+++ b/libgcc/config/i386/gnu-unwind.h
@@ -32,9 +32,100 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
 
 #ifdef __x86_64__
 
-/*
- * TODO: support for 64 bits needs to be implemented.
- */
+#define MD_FALLBACK_FRAME_STATE_FOR x86_gnu_fallback_frame_state
+
+static _Unwind_Reason_Code
+x86_gnu_fallback_frame_state
+(struct _Unwind_Context *context, _Unwind_FrameState *fs)
+{
+  static const unsigned char gnu_sigtramp_code[] =
+  {
+/* rpc_wait_trampoline: */
+0x48, 0xc7, 0xc0, 0xe7, 0xff, 0xff, 0xff,/* mov$-25,%rax */
+0x0f, 0x05,  /* syscall */
+0x49, 0x89, 0x04, 0x24,  /* mov%rax,(%r12) */
+0x48, 0x89, 0xdc,/* mov%rbx,%rsp */
+
+/* trampoline: */
+0x5f,/* pop%rdi */
+0x5e,/* pop%rsi */
+0x5a,/* pop%rdx */
+0x48, 0x83, 0xc4, 0x08,  /* add$0x8,%rsp */
+0x41, 0xff, 0xd5,/* call   *%r13 */
+
+/* RA HERE */
+0x48, 0x8b, 0x7c, 0x24, 0x10,/* mov0x10(%rsp),%rdi */
+0xc3,/* ret */
+
+/* firewall: */
+0xf4,/* hlt */
+  };
+
+  const size_t gnu_sigtramp_len = sizeof gnu_sigtramp_code;
+  const size_t gnu_sigtramp_tail = 7; /* length of tail after RA */
+
+  struct stack_contents {
+void *sigreturn_addr;
+void *sigreturn_returns_here;
+struct sigcontext *return_scp;
+  } *stack_contents;
+  struct sigcontext *scp;
+  unsigned long usp;
+
+  unsigned char *adjusted_pc = (unsigned char*)(context->ra) +
+gnu_sigtramp_tail - gnu_sigtramp_len;
+  if (memcmp (adjusted_pc, gnu_sigtramp_code, gnu_sigtramp_len))
+return _URC_END_OF_STACK;
+
+  stack_contents = context->cfa;
+
+  scp = stack_contents->return_scp;
+  usp = scp->sc_ursp;
+
+  fs->regs.reg[0].loc.offset = (unsigned long)>sc_rax - usp;
+  fs->regs.reg[1].loc.offset = (unsigned long)>sc_rdx - usp;
+  fs->regs.reg[2].loc.offset = (unsigned long)>sc_rcx - usp;
+  fs->regs.reg[3].loc.offset = (unsigned long)>sc_rbx - usp;
+  fs->regs.reg[4].loc.offset = (unsigned long)>sc_rsi - usp;
+  fs->regs.reg[5].loc.offset = (unsigned long)>sc_rdi - usp;
+  fs->regs.reg[6].loc.offset = (unsigned long)>sc_rbp - usp;
+  fs->regs.reg[8].loc.offset = (unsigned long)>sc_r8 - usp;
+  fs->regs.reg[9].loc.offset = (unsigned long)>sc_r9 - usp;
+  fs->regs.reg[10].loc.offset = (unsigned long)>sc_r10 - usp;
+  fs->regs.reg[11].loc.offset = (unsigned long)>sc_r11 - usp;
+  fs->regs.reg[12].loc.offset = (unsigned long)>sc_r12 - usp;
+  fs->regs.reg[13].loc.offset = (unsigned long)>sc_r13 - usp;
+  fs->regs.reg[14].loc.offset = (unsigned long)>sc_r14 - usp;
+  fs->regs.reg[15].loc.offset = (unsigned long)>sc_r15 - usp;
+  fs->regs.reg[16].loc.offset = (unsigned long)>sc_rip - usp;
+
+  /* Register 7 is rsp  */
+  fs->regs.cfa_how = CFA_REG_OFFSET;
+  fs->regs.cfa_reg = 7;
+  fs->regs.cfa_offset = usp - (unsigned long) context->cfa;
+
+  fs->regs.how[0] = REG_SAVED_OFFSET;
+  fs->regs.how[1] = REG_SAVED_OFFSET;
+  fs->regs.how[2] = REG_SAVED_OFFSET;
+  fs->regs.how[3] = REG_SAVED_OFFSET;
+  fs->regs.how[4] = REG_SAVED_OFFSET;
+  fs->regs.how[5] = REG_SAVED_OFFSET;
+  fs->regs.how[6] = REG_SAVED_OFFSET;
+  fs->regs.how[8] = REG_SAVED_OFFSET;
+  fs->regs.how[9] = REG_SAVED_OFFSET;
+  fs->regs.how[10] = REG_SAVED_OFFSET;
+  fs->regs.how[11] = REG_SAVED_OFFSET;
+  fs->regs.how[12] = REG_SAVED_OFFSET;
+  fs->regs.how[13] = REG_SAVED_OFFSET;
+  fs->regs.how[14] = REG_SAVED_OFFSET;
+  fs->regs.how[15] = REG_SAVED_OFFSET;
+  fs->regs.how[16] = REG_SAVED_OFFSET;
+
+  fs->retaddr_column = 16;
+  fs->signal_frame = 1;
+
+  return _URC_NO_REASON;
+}
 
 #else /* ifdef __x86_64__  */
 
-- 
2.43.0




[PATCH hurd] rumpdisk: do not open device if block size is 0

2024-02-28 Thread Flavio Cruz
Currently, if we do:

$ ls /dev/cd0/

The computer seems to get stuck, caused by the divide by 0 in the
rumpdisk server in device_get_status. I noticed that if we have no disk in the
cdrom device, we can still open it but block and media size will be 0
and the message "cd0 dos partition I/O error" will be printed to the
console. To avoid this problem, we check the block size and throw an error
when it is 0. This also works correctly when a disk actually exists.

This should help fix the perl and likely the vim test suites that are
currently failing in https://buildd.debian.org/.
---
 rumpdisk/block-rump.c | 23 +--
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/rumpdisk/block-rump.c b/rumpdisk/block-rump.c
index a29ebe73..71435f20 100644
--- a/rumpdisk/block-rump.c
+++ b/rumpdisk/block-rump.c
@@ -277,18 +277,25 @@ rumpdisk_device_open (mach_port_t reply_port, 
mach_msg_type_name_t reply_port_ty
   return rump_errno2host (errno);
 }
 
-  ret = rump_sys_ioctl (fd, DIOCGMEDIASIZE, _size);
+  ret = rump_sys_ioctl (fd, DIOCGSECTORSIZE, _size);
   if (ret < 0)
 {
-  mach_print ("DIOCGMEDIASIZE ioctl fails\n");
+  mach_print ("DIOCGSECTORSIZE ioctl fails\n");
   pthread_rwlock_unlock (_rwlock);
   return rump_errno2host (errno);
 }
 
-  ret = rump_sys_ioctl (fd, DIOCGSECTORSIZE, _size);
+  if (block_size == 0) {
+mach_print ("Unable to get block size\n");
+rump_sys_close (fd);
+pthread_rwlock_unlock (_rwlock);
+return D_IO_ERROR;
+  }
+
+  ret = rump_sys_ioctl (fd, DIOCGMEDIASIZE, _size);
   if (ret < 0)
 {
-  mach_print ("DIOCGSECTORSIZE ioctl fails\n");
+  mach_print ("DIOCGMEDIASIZE ioctl fails\n");
   pthread_rwlock_unlock (_rwlock);
   return rump_errno2host (errno);
 }
@@ -509,8 +516,12 @@ rumpdisk_device_get_status (void *d, dev_flavor_t flavor, 
dev_status_t status,
   break;
 case DEV_GET_RECORDS:
   status[DEV_GET_RECORDS_RECORD_SIZE] = bd->block_size;
-  status[DEV_GET_RECORDS_DEVICE_RECORDS] =
-   bd->media_size / (unsigned long long) bd->block_size;
+  if (bd->block_size == 0)
+   status[DEV_GET_RECORDS_DEVICE_RECORDS] = 0;
+  else {
+   status[DEV_GET_RECORDS_DEVICE_RECORDS] =
+ bd->media_size / (unsigned long long) bd->block_size;
+  }
   *count = 2;
   break;
 default:
-- 
2.43.0




[PATCH gnumach] Check for null ports in task_set_essential, task_set_name and thread_set_name.

2024-02-24 Thread Flavio Cruz
Otherwise, it is easy to crash the kernel if userland passes arbitrary port
names.
---
 kern/task.c   | 6 ++
 kern/thread.c | 3 +++
 2 files changed, 9 insertions(+)

diff --git a/kern/task.c b/kern/task.c
index 60ab4d7..dfba04d 100644
--- a/kern/task.c
+++ b/kern/task.c
@@ -1165,6 +1165,9 @@ task_set_name(
task_t  task,
const_kernel_debug_name_t   name)
 {
+   if (task == TASK_NULL)
+   return KERN_INVALID_ARGUMENT;
+
strncpy(task->name, name, sizeof task->name - 1);
task->name[sizeof task->name - 1] = '\0';
return KERN_SUCCESS;
@@ -1181,6 +1184,9 @@ task_set_essential(
task_t  task,
boolean_t   essential)
 {
+   if (task == TASK_NULL)
+   return KERN_INVALID_ARGUMENT;
+
task->essential = !!essential;
return KERN_SUCCESS;
 }
diff --git a/kern/thread.c b/kern/thread.c
index 2eab1ca..eb73590 100644
--- a/kern/thread.c
+++ b/kern/thread.c
@@ -2640,6 +2640,9 @@ thread_set_name(
thread_tthread,
const_kernel_debug_name_t   name)
 {
+   if (thread == THREAD_NULL)
+   return KERN_INVALID_ARGUMENT;
+
strncpy(thread->name, name, sizeof thread->name - 1);
thread->name[sizeof thread->name - 1] = '\0';
return KERN_SUCCESS;
-- 
2.39.2




[PATCH v2] Port GDB to Hurd x86_64.

2024-02-23 Thread Flavio Cruz
This port extends the existing i686 port to support x86_64 by trying to
reuse existing code whenever it makes sense.

* gdb/amd64-gnu-tdep.c: Adds logic for handling signal frames and
  position of amd64 registers in the different Hurd structs.
  The signal code is very similar to i686, except the trampoline code
  is adapted.
* gdb/config/i386/nm-i386gnu.h: renamed to gdb/config/i386/nm-x86-gnu.h
  and adapt it for x86_64.
* gdb/config/i386/i386gnu.mn: renamed to gdb/config/i386/nm-x86-gnu.mn
  and reuse it for x86_64.
* gdb/configure.host: recognize gnu64 as a host.
* gdb/configure.nat: recognize gnu64 host and update existing i386gnu to
  reuse the new shared files.
* gdb/configure.tgt: recognize x86_64-*-gnu* triplet and use
  amd64-gnu-tdep.c.
* gdb/i386-gnu-tdep.c: added i386_gnu_thread_state_reg_offset that is
  copied from i386-gnu-nat.c. This makes it similar to amd64.
* gdb/i386-gnu-nat.c: rename it to x86-gnu-nat.c since we reuse this for
  i386 and amd64. Updated REG_ADDR to use one of the structures. Added
  VALID_REGISTER to make sure it's a register we can provide at this time
  (not all of them are available in amd64). FLAGS_REGISTER is either rfl
  or efl depending on the arch. Renamed functions and class from i386 to x86
  whenever they can be reused.

Tested on Hurd x86_64 and i686.
---

I addressed John's comments and moved amd64_gnu_thread_state_* and
i386_gnu_thread_state_* to x86-gnu-nat.c. The new patch also contains a few
changes that makes backtracing through shared libraries work.


 gdb/amd64-gnu-tdep.c  | 230 ++
 .../i386/{nm-i386gnu.h => nm-x86-gnu.h}   |   7 +
 gdb/config/i386/{i386gnu.mn => x86-gnu.mn}|   0
 gdb/configure.host|   1 +
 gdb/configure.nat |  27 +-
 gdb/configure.tgt |   6 +-
 gdb/i386-gnu-tdep.c   |  13 +-
 gdb/{i386-gnu-nat.c => x86-gnu-nat.c} | 171 +
 8 files changed, 399 insertions(+), 56 deletions(-)
 create mode 100644 gdb/amd64-gnu-tdep.c
 rename gdb/config/i386/{nm-i386gnu.h => nm-x86-gnu.h} (83%)
 rename gdb/config/i386/{i386gnu.mn => x86-gnu.mn} (100%)
 rename gdb/{i386-gnu-nat.c => x86-gnu-nat.c} (69%)

diff --git a/gdb/amd64-gnu-tdep.c b/gdb/amd64-gnu-tdep.c
new file mode 100644
index 000..0776ec70dd7
--- /dev/null
+++ b/gdb/amd64-gnu-tdep.c
@@ -0,0 +1,230 @@
+/* Target-dependent code for the GNU Hurd.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see .  */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "osabi.h"
+#include "solib-svr4.h"
+
+#include "amd64-tdep.h"
+#include "glibc-tdep.h"
+
+/* Recognizing signal handler frames.  */
+
+/* When the GNU/Hurd libc calls a signal handler, the return address points
+   inside the trampoline assembly snippet.
+
+   If the trampoline function name can not be identified, we resort to reading
+   memory from the process in order to identify it.  */
+
+static const gdb_byte gnu_sigtramp_code[] =
+{
+/* rpc_wait_trampoline: */
+  0x48, 0xc7, 0xc0, 0xe7, 0xff, 0xff, 0xff,/* mov$-25,%rax */
+  0x0f, 0x05,  /* syscall */
+  0x49, 0x89, 0x04, 0x24,  /* mov%rax,(%r12) */
+  0x48, 0x89, 0xdc,/* mov%rbx,%rsp */
+
+/* trampoline: */
+  0x5f,/* pop%rdi */
+  0x5e,/* pop%rsi */
+  0x5a,/* pop%rdx */
+  0x48, 0x83, 0xc4, 0x08,  /* add$0x8,%rsp */
+  0x41, 0xff, 0xd5,/* call   *%r13 */
+
+/* RA HERE */
+  0x48, 0x8b, 0x7c, 0x24, 0x10,/* mov
0x10(%rsp),%rdi */
+  0xc3,/* ret */
+
+/* firewall: */
+  0xf4,/* hlt */
+};
+
+#define GNU_SIGTRAMP_LEN (sizeof gnu_sigtramp_code)
+#define GNU_SIGTRAMP_TAIL 7/* length of tail after RA */
+
+/* If THIS_FRAME is a sigtramp routine, return the address of the
+   start of the routine.  Otherwise, return 0.  */
+
+static CORE_ADDR
+amd64_gnu_sigtramp_start (frame_info_ptr this_frame)

[PATCH gnumach] x86_64: avoid iterating over the message twice in copyoutmsg/copyinmsg for faster RPCs.

2024-02-19 Thread Flavio Cruz
This is a follow up to
https://git.savannah.gnu.org/cgit/hurd/gnumach.git/commit/?id=69620634858b2992e1a362e33c95d9a8ee57bce7
where we made inlined ports 8 bytes long to avoid resizing.

The last thing that copy{in,out}msg were doing was just updating
msgt_size field since that's required for kernel stub code and implicitly
assumed by IPC code. This was moved into ipc_kmsg_copy{in,out}_body.

For a 32 bit userland, the code also stops updating
msgt_size for out of line ports, same as the 64 bit userland.
---
 i386/i386/locore.h |   6 +++
 ipc/ipc_kmsg.c |  52 +--
 x86_64/copy_user.c | 123 +
 3 files changed, 66 insertions(+), 115 deletions(-)

diff --git a/i386/i386/locore.h b/i386/i386/locore.h
index 374c8cf..217e6de 100644
--- a/i386/i386/locore.h
+++ b/i386/i386/locore.h
@@ -50,7 +50,13 @@ extern int discover_x86_cpu_type (void);
 extern int copyin (const void *userbuf, void *kernelbuf, size_t cn);
 extern int copyinmsg (const void *userbuf, void *kernelbuf, size_t cn, size_t 
kn);
 extern int copyout (const void *kernelbuf, void *userbuf, size_t cn);
+#ifdef USER32
 extern int copyoutmsg (const void *kernelbuf, void *userbuf, size_t cn);
+#else
+static inline int copyoutmsg (const void *kernelbuf, void *userbuf, size_t cn) 
{
+   return copyout (kernelbuf, userbuf, cn);
+}
+#endif
 
 extern int inst_fetch (int eip, int cs);
 
diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c
index bd84380..6a7ad3c 100644
--- a/ipc/ipc_kmsg.c
+++ b/ipc/ipc_kmsg.c
@@ -1321,7 +1321,7 @@ ipc_kmsg_copyin_body(
mach_msg_type_number_t number;
boolean_t is_inline, longform, dealloc, is_port;
vm_offset_t data;
-   uint64_t length;
+   vm_size_t length;
kern_return_t kr;
 
type = (mach_msg_type_long_t *) saddr;
@@ -1355,7 +1355,8 @@ ipc_kmsg_copyin_body(
 
is_port = MACH_MSG_TYPE_PORT_ANY(name);
 
-   if ((is_port && (size != PORT_T_SIZE_IN_BITS)) ||
+   if ((is_port && !is_inline && (size != 
PORT_NAME_T_SIZE_IN_BITS)) ||
+   (is_port && is_inline && (size != PORT_T_SIZE_IN_BITS)) ||
 #ifndef __x86_64__
(longform && ((type->msgtl_header.msgt_name != 0) ||
  (type->msgtl_header.msgt_size != 0) ||
@@ -1396,11 +1397,22 @@ ipc_kmsg_copyin_body(
if (length == 0)
data = 0;
else if (is_port) {
+   const vm_size_t user_length = length;
+   /*
+* In 64 bit architectures, out of line port 
names are
+* represented as an array of mach_port_name_t 
which are
+* smaller than mach_port_t.
+*/
+   if (sizeof(mach_port_name_t) != 
sizeof(mach_port_t)) {
+   length = sizeof(mach_port_t) * number;
+   type->msgtl_size = sizeof(mach_port_t) 
* 8;
+   }
+
data = kalloc(length);
if (data == 0)
goto invalid_memory;
 
-   if (sizeof(mach_port_name_t) != 
sizeof(mach_port_t))
+   if (user_length != length)
{
mach_port_name_t *src = 
(mach_port_name_t*)addr;
mach_port_t *dst = (mach_port_t*)data;
@@ -1416,7 +1428,7 @@ ipc_kmsg_copyin_body(
goto invalid_memory;
}
if (dealloc &&
-   (vm_deallocate(map, addr, length) != 
KERN_SUCCESS)) {
+   (vm_deallocate(map, addr, user_length) != 
KERN_SUCCESS)) {
kfree(data, length);
goto invalid_memory;
}
@@ -2372,7 +2384,7 @@ ipc_kmsg_copyout_body(
mach_msg_type_size_t size;
mach_msg_type_number_t number;
boolean_t is_inline, longform, is_port;
-   uint64_t length;
+   vm_size_t length;
vm_offset_t addr;
 
type = (mach_msg_type_long_t *) saddr;
@@ -2406,18 +2418,28 @@ ipc_kmsg_copyout_body(
ipc_object_t *objects;
mach_msg_type_number_t i;
 
-   if (!is_inline && (length != 0)) {
-   /* first allocate memory in the map */
-   uint64_t allocated = length;
+   if (!is_inline) {
+ 

[PATCH glibc] Implement setcontext/getcontext/makecontext/swapcontext for Hurd x86_64

2024-02-17 Thread Flavio Cruz
Tested with the tests provided by glibc plus some other toy examples.
---
 sysdeps/mach/hurd/x86_64/Makefile  |   4 +
 sysdeps/mach/hurd/x86_64/__start_context.S |  49 +
 sysdeps/mach/hurd/x86_64/getcontext.S  |  68 
 sysdeps/mach/hurd/x86_64/makecontext.c | 119 
 sysdeps/mach/hurd/x86_64/setcontext.S  |  96 +
 sysdeps/mach/hurd/x86_64/swapcontext.S | 120 +
 6 files changed, 456 insertions(+)
 create mode 100644 sysdeps/mach/hurd/x86_64/__start_context.S
 create mode 100644 sysdeps/mach/hurd/x86_64/getcontext.S
 create mode 100644 sysdeps/mach/hurd/x86_64/makecontext.c
 create mode 100644 sysdeps/mach/hurd/x86_64/setcontext.S
 create mode 100644 sysdeps/mach/hurd/x86_64/swapcontext.S

diff --git a/sysdeps/mach/hurd/x86_64/Makefile 
b/sysdeps/mach/hurd/x86_64/Makefile
index 80cf2eb6..2b43f5d6 100644
--- a/sysdeps/mach/hurd/x86_64/Makefile
+++ b/sysdeps/mach/hurd/x86_64/Makefile
@@ -3,3 +3,7 @@ ifeq ($(subdir),conform)
 # (missing SA_NOCLDWAIT)
 conformtest-xfail-conds += x86_64-gnu
 endif
+
+ifeq ($(subdir),stdlib)
+sysdep_routines += __start_context
+endif
diff --git a/sysdeps/mach/hurd/x86_64/__start_context.S 
b/sysdeps/mach/hurd/x86_64/__start_context.S
new file mode 100644
index ..3cb4c6b5
--- /dev/null
+++ b/sysdeps/mach/hurd/x86_64/__start_context.S
@@ -0,0 +1,49 @@
+/* Copyright (C) 2024 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 
+
+/* This is the helper code which gets called if a function which is
+   registered with 'makecontext' returns.  In this case we have to
+   install the context listed in the uc_link element of the context
+   'makecontext' manipulated at the time of the 'makecontext' call.
+   If the pointer is NULL the process must terminate.  */
+
+
+ENTRY(__start_context)
+   /* This removes the parameters passed to the function given to
+  'makecontext' from the stack.  RBX contains the address
+  on the stack pointer for the next context.  */
+   movq%rbx, %rsp
+
+   /* Don't use pop here so that stack is aligned to 16 bytes.  */
+   movq(%rsp), %rdi/* This is the next context.  */
+   testq   %rdi, %rdi
+   je  2f  /* If it is zero exit.  */
+
+   call__setcontext
+   /* If this returns (which can happen if __sigprocmask fails) we'll
+  exit the program with the return error value (-1).  */
+   movq%rax,%rdi
+
+2:
+   callHIDDEN_JUMPTARGET(exit)
+   /* The 'exit' call should never return.  In case it does cause
+  the process to terminate.  */
+L(hlt):
+   hlt
+END(__start_context)
diff --git a/sysdeps/mach/hurd/x86_64/getcontext.S 
b/sysdeps/mach/hurd/x86_64/getcontext.S
new file mode 100644
index ..ef431be1
--- /dev/null
+++ b/sysdeps/mach/hurd/x86_64/getcontext.S
@@ -0,0 +1,68 @@
+/* Save current context.
+   Copyright (C) 2024 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 "ucontext_i.h"
+
+
+ENTRY(__getcontext)
+   /* Save the preserved registers, the registers used for passing
+  args, and the return address.  */
+   movq%rbx, oRBX(%rdi)
+   movq%rbp, oRBP(%rdi)
+   movq%r12, oR12(%rdi)
+   movq%r13, oR13(%rdi)
+   movq%r14, oR14(%rdi)
+   movq%r15, oR15(%rdi)
+
+   movq%rdi, oRDI(%rdi)
+   movq%rsi, oRSI(%rdi)
+   movq%rdx, oRDX(%rdi)
+   movq%rcx, oRCX(%rdi)
+

[PATCH glibc] Use proc_getchildren_rusage when available in getrusage and times.

2024-02-17 Thread Flavio Cruz
---
 config.h.in|   3 +
 sysdeps/mach/hurd/configure| 174 +
 sysdeps/mach/hurd/configure.ac |  19 
 sysdeps/mach/hurd/getrusage.c  |   8 +-
 sysdeps/mach/hurd/times.c  |  18 +++-
 5 files changed, 219 insertions(+), 3 deletions(-)

diff --git a/config.h.in b/config.h.in
index 44a34072..2f0669e1 100644
--- a/config.h.in
+++ b/config.h.in
@@ -159,6 +159,9 @@
 /* Mach/i386 specific: define if the `i386_set_gdt' RPC is available.  */
 #undef HAVE_I386_SET_GDT
 
+/* Hurd specific; define if the `proc_getchildren_rusage' RPC is available.  */
+#undef HAVE_HURD_PROC_GETCHILDREN_RUSAGE
+
 /* Define if inlined system calls are available.  */
 #undef HAVE_INLINED_SYSCALLS
 
diff --git a/sysdeps/mach/hurd/configure b/sysdeps/mach/hurd/configure
index 33d3e1fc..cd5af1cd 100644
--- a/sysdeps/mach/hurd/configure
+++ b/sysdeps/mach/hurd/configure
@@ -45,6 +45,180 @@ if test "x$libc_cv_hurd_version" != xok; then
   as_fn_error $? "Hurd headers not installed or too old" "$LINENO" 5
 fi
 
+
+
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles 
long lines and -e" >&5
+printf %s "checking for grep that handles long lines and -e... " >&6; }
+if test ${ac_cv_path_GREP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+'') as_dir=./ ;;
+*/) ;;
+*) as_dir=$as_dir/ ;;
+  esac
+for ac_prog in grep ggrep
+   do
+for ac_exec_ext in '' $ac_executable_extensions; do
+  ac_path_GREP="$as_dir$ac_prog$ac_exec_ext"
+  as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  printf %s 0123456789 >"conftest.in"
+  while :
+  do
+cat "conftest.in" "conftest.in" >"conftest.tmp"
+mv "conftest.tmp" "conftest.in"
+cp "conftest.in" "conftest.nl"
+printf "%s\n" 'GREP' >> "conftest.nl"
+"$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" 
>"conftest.out" 2>/dev/null || break
+diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+as_fn_arith $ac_count + 1 && ac_count=$as_val
+if test $ac_count -gt ${ac_path_GREP_max-0}; then
+  # Best one so far, save it but keep looking for a better one
+  ac_cv_path_GREP="$ac_path_GREP"
+  ac_path_GREP_max=$ac_count
+fi
+# 10*(2^10) chars as input seems more than enough
+test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+  $ac_path_GREP_found && break 3
+done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+as_fn_error $? "no acceptable grep could be found in 
$PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+printf "%s\n" "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+printf %s "checking for egrep... " >&6; }
+if test ${ac_cv_path_EGREP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+ if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+'') as_dir=./ ;;
+*/) ;;
+*) as_dir=$as_dir/ ;;
+  esac
+for ac_prog in egrep
+   do
+for ac_exec_ext in '' $ac_executable_extensions; do
+  ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext"
+  as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  printf %s 0123456789 >"conftest.in"
+  while :
+  do
+cat "conftest.in" "conftest.in" >"conftest.tmp"
+mv "conftest.tmp" "conftest.in"
+cp "conftest.in" "conftest.nl"
+printf "%s\n" 'EGREP' >> "conftest.nl"
+"$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || 
break
+diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+as_fn_arith $ac_count + 1 && ac_count=$as_val
+if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+  # Best one so far, save it but keep looking for a better one
+  ac_cv_path_EGREP="$ac_path_EGREP"
+  ac_path_EGREP_max=$ac_count
+fi
+# 

Patch series for children process resource accounting

2024-02-16 Thread Flavio Cruz
These patches implement getrusage(RUSAGE_CHILDREN, _) and populate
child related data in times(_). This should fix the problem we have
with building the latest grep which uses times(_) to get the cpu cycles in the 
test
suite: 
https://buildd.debian.org/status/fetch.php?pkg=grep=hurd-i386=3.11-4=1704383469=0





[PATCH glibc] Use proc_getchildren_rusage when available in getrusage and times.

2024-02-16 Thread Flavio Cruz
---
 config.h.in   |  3 +++
 sysdeps/mach/configure| 28 
 sysdeps/mach/configure.ac |  9 +
 sysdeps/mach/hurd/getrusage.c |  8 ++--
 sysdeps/mach/hurd/times.c | 18 +-
 5 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/config.h.in b/config.h.in
index 44a34072..2f0669e1 100644
--- a/config.h.in
+++ b/config.h.in
@@ -159,6 +159,9 @@
 /* Mach/i386 specific: define if the `i386_set_gdt' RPC is available.  */
 #undef HAVE_I386_SET_GDT
 
+/* Hurd specific; define if the `proc_getchildren_rusage' RPC is available.  */
+#undef HAVE_HURD_PROC_GETCHILDREN_RUSAGE
+
 /* Define if inlined system calls are available.  */
 #undef HAVE_INLINED_SYSCALLS
 
diff --git a/sysdeps/mach/configure b/sysdeps/mach/configure
index f15160d0..d579c301 100644
--- a/sysdeps/mach/configure
+++ b/sysdeps/mach/configure
@@ -521,5 +521,33 @@ if test $libc_cv_mach_i386_gdt = yes; then
 
 fi
 
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for 
proc_getchildren_rusage in process.defs" >&5
+printf %s "checking for proc_getchildren_rusage in process.defs... " >&6; }
+if test ${libc_cv_hurd_proc_getchildren_rusage+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include 
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "proc_getchildren_rusage" >/dev/null 2>&1
+then :
+  libc_cv_hurd_proc_getchildren_rusage=yes
+else $as_nop
+  libc_cv_hurd_proc_getchildren_rusage=no
+fi
+rm -rf conftest*
+
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: 
$libc_cv_hurd_proc_getchildren_rusage" >&5
+printf "%s\n" "$libc_cv_hurd_proc_getchildren_rusage" >&6; }
+if test $libc_cv_hurd_proc_getchildren_rusage = yes; then
+  printf "%s\n" "#define HAVE_HURD_PROC_GETCHILDREN_RUSAGE 1" >>confdefs.h
+
+fi
+
 CPPFLAGS=$OLD_CPPFLAGS
 
diff --git a/sysdeps/mach/configure.ac b/sysdeps/mach/configure.ac
index 730fb25d..db1e453f 100644
--- a/sysdeps/mach/configure.ac
+++ b/sysdeps/mach/configure.ac
@@ -104,4 +104,13 @@ if test $libc_cv_mach_i386_gdt = yes; then
   AC_DEFINE([HAVE_I386_SET_GDT])
 fi
 
+AC_CACHE_CHECK(for proc_getchildren_rusage in process.defs,
+  libc_cv_hurd_proc_getchildren_rusage, [dnl
+AC_EGREP_HEADER(proc_getchildren_rusage, hurd/process.defs,
+   libc_cv_hurd_proc_getchildren_rusage=yes,
+   libc_cv_hurd_proc_getchildren_rusage=no)])
+if test $libc_cv_hurd_proc_getchildren_rusage = yes; then
+  AC_DEFINE([HAVE_HURD_PROC_GETCHILDREN_RUSAGE])
+fi
+
 CPPFLAGS=$OLD_CPPFLAGS
diff --git a/sysdeps/mach/hurd/getrusage.c b/sysdeps/mach/hurd/getrusage.c
index 7be4dd17..8151c297 100644
--- a/sysdeps/mach/hurd/getrusage.c
+++ b/sysdeps/mach/hurd/getrusage.c
@@ -75,9 +75,13 @@ __getrusage (enum __rusage_who who, struct rusage *usage)
   break;
 
 case RUSAGE_CHILDREN:
-  /* XXX Not implemented yet.  However, zero out USAGE to be
- consistent with the wait3 and wait4 functions.  */
+#ifdef HAVE_HURD_PROC_GETCHILDREN_RUSAGE
+  err = __USEPORT (PROC, __proc_getchildren_rusage (port, usage));
+  if (err)
+   return __hurd_fail (err);
+#else
   memset (usage, 0, sizeof (struct rusage));
+#endif
 
   break;
 
diff --git a/sysdeps/mach/hurd/times.c b/sysdeps/mach/hurd/times.c
index 0c3880d5..3e384dd6 100644
--- a/sysdeps/mach/hurd/times.c
+++ b/sysdeps/mach/hurd/times.c
@@ -32,6 +32,13 @@ clock_from_time_value (const time_value_t *t)
   return t->seconds * 100 + t->microseconds;
 }
 
+#ifdef HAVE_HURD_PROC_GETCHILDREN_RUSAGE
+static inline clock_t
+clock_from_timeval (const struct timeval *t) {
+  return t->tv_sec * 100 + t->tv_usec;
+}
+#endif
+
 /* Store the CPU time used by this process and all its
dead children (and their dead children) in BUFFER.
Return the elapsed real time, or (clock_t) -1 for errors.
@@ -62,8 +69,17 @@ __times (struct tms *tms)
   tms->tms_stime = (clock_from_time_value (_time)
+ clock_from_time_value (_time));
 
-  /* XXX This can't be implemented until getrusage(RUSAGE_CHILDREN) can be.  */
+#ifdef HAVE_HURD_PROC_GETCHILDREN_RUSAGE
+  struct rusage child_rusage;
+  err = __USEPORT (PROC, __proc_getchildren_rusage (port, _rusage));
+  if (err)
+return __hurd_fail (err);
+
+  tms->tms_cutime = clock_from_timeval (_rusage.ru_utime);
+  tms->tms_cstime = clock_from_timeval (_rusage.ru_stime);
+#else
   tms->tms_cutime = tms->tms_cstime = 0;
+#endif
 
   __host_get_time (__mach_host_self (), );
 
-- 
2.39.2




[PATCH hurd] Add proc_getchildren_rusage RPC and track rusage for children and descendants

2024-02-16 Thread Flavio Cruz
---
 hurd/process.defs | 6 ++
 proc/info.c   | 8 
 proc/proc.h   | 4 +++-
 proc/wait.c   | 2 ++
 4 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/hurd/process.defs b/hurd/process.defs
index 9a8b3a1..007aa2b 100644
--- a/hurd/process.defs
+++ b/hurd/process.defs
@@ -466,3 +466,9 @@ simpleroutine proc_reauthenticate_reassign (
that the user has received from auth_user_authenticate call.  */
 simpleroutine proc_reauthenticate_complete (
process: process_t);
+
+/* Returns the rusage information for the children that were waited
+ * for plus all their descendants.  */
+routine proc_getchildren_rusage (
+   process: process_t;
+   out children_rusage: rusage_t);
diff --git a/proc/info.c b/proc/info.c
index 2d85662..e5b0f47 100644
--- a/proc/info.c
+++ b/proc/info.c
@@ -1093,3 +1093,11 @@ S_proc_get_exe (struct proc *callerp,
   return 0;
 }
 
+kern_return_t
+S_proc_getchildren_rusage (struct proc *p, struct rusage *ru)
+{
+  if (!p)
+return EOPNOTSUPP;
+  *ru = p->p_child_rusage;
+  return 0;
+}
diff --git a/proc/proc.h b/proc/proc.h
index a83a509..bbba095 100644
--- a/proc/proc.h
+++ b/proc/proc.h
@@ -76,7 +76,9 @@ struct proc
   int p_sigcode;
   struct rusage p_rusage;  /* my usage if I'm dead, to return via wait */
 
-  struct rusage p_child_rusage;/* accumulates p_rusage of all dead 
children */
+  /* Accumulates p_rusage of all dead children, including
+   * grandchildren and their descendants.  */
+  struct rusage p_child_rusage;
 
   unsigned int p_exec:1;   /* has called proc_mark_exec */
   unsigned int p_stopped:1;/* has called proc_mark_stop */
diff --git a/proc/wait.c b/proc/wait.c
index 4551d28..a31b0e7 100644
--- a/proc/wait.c
+++ b/proc/wait.c
@@ -156,6 +156,8 @@ alert_parent (struct proc *p)
 {
   /* We accumulate the aggregate usage stats of all our dead children.  */
   rusage_add (>p_parent->p_child_rusage, >p_rusage);
+  /* ... and descendants.  */
+  rusage_add (>p_parent->p_child_rusage, >p_child_rusage);
 
   send_signal (p->p_parent->p_msgport, SIGCHLD, CLD_EXITED, 
p->p_parent->p_task);
 
-- 
2.39.2




[PATCH v2] Port GDB to Hurd x86_64.

2024-02-14 Thread Flavio Cruz
This port extends the existing i686 port to support x86_64 by trying to
reuse existing code whenever it makes sense.

* gdb/amd64-gnu-tdep.c: Adds logic for handling signal frames and
  position of amd64 registers in the different Hurd structs, including
  i386_thread_state. The signal code is very similar to i686, except the
  trampoline code is adapted.
* gdb/amd64-gnu-tdep.h: export register offsets for x86-gnu-nat.c.
* gdb/config/i386/nm-i386gnu.h: renamed to gdb/config/i386/nm-x86-gnu.h
  and adapt it for x86_64.
* gdb/config/i386/i386gnu.mn: renamed to gdb/config/i386/nm-x86-gnu.mn
  and reuse it for x86_64.
* gdb/configure.host: recognize gnu64 as a host.
* gdb/configure.nat: recognize gnu64 host and update existing i386gnu to
  reuse the new shared files.
* gdb/configure.tgt: recognize x86_64-*-gnu* triplet and use
  amd64-gnu-tdep.c.
* gdb/i386-gnu-tdep.c: added i386_gnu_thread_state_reg_offset that is
  copied from i386-gnu-nat.c. This makes it similar to amd64.
* gdb/i386-gnu-tdep.h: export register offsets and number of registers.
* gdb/i386-gnu-nat.c: rename it to x86-gnu-nat.c since we reuse this for
  i386 and amd64. Updated REG_ADDR to use one of the structures. Added
  VALID_REGISTER to make sure it's a register we can provide at this time
  (not all of them are available in amd64). FLAGS_REGISTER is either rfl
  or efl depending on the arch. Renamed functions and class from i386 to x86
  whenever they can be reused.

Tested on Hurd x86_64 and i686.
---

Latest changes:
- Changed svr4_ilp32_fetch_link_map_offsets to
  svr4_lp64_fetch_link_map_offsets in amd64-gnu-tdep.c (duh).
- Added set_gdbarch_* to work better with the glibc and shared
  library features like TLS and PLT in amd64-gnu-tdep.c and also
  i386-gnu-tdep.c

It does seem to work with shared libraries now and I can backtrace inside
library functions from libhurduser up to libc.

 gdb/amd64-gnu-tdep.c  | 267 ++
 gdb/amd64-gnu-tdep.h  |  29 ++
 .../i386/{nm-i386gnu.h => nm-x86-gnu.h}   |   7 +
 gdb/config/i386/{i386gnu.mn => x86-gnu.mn}|   0
 gdb/configure.host|   1 +
 gdb/configure.nat |  27 +-
 gdb/configure.tgt |   6 +-
 gdb/i386-gnu-tdep.c   |  47 ++-
 gdb/i386-gnu-tdep.h   |  29 ++
 gdb/{i386-gnu-nat.c => x86-gnu-nat.c} | 128 +
 10 files changed, 479 insertions(+), 62 deletions(-)
 create mode 100644 gdb/amd64-gnu-tdep.c
 create mode 100644 gdb/amd64-gnu-tdep.h
 rename gdb/config/i386/{nm-i386gnu.h => nm-x86-gnu.h} (83%)
 rename gdb/config/i386/{i386gnu.mn => x86-gnu.mn} (100%)
 create mode 100644 gdb/i386-gnu-tdep.h
 rename gdb/{i386-gnu-nat.c => x86-gnu-nat.c} (75%)

diff --git a/gdb/amd64-gnu-tdep.c b/gdb/amd64-gnu-tdep.c
new file mode 100644
index 000..a5e67df5f21
--- /dev/null
+++ b/gdb/amd64-gnu-tdep.c
@@ -0,0 +1,267 @@
+/* Target-dependent code for the GNU Hurd.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see .  */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "osabi.h"
+#include "solib-svr4.h"
+
+#include "amd64-tdep.h"
+#include "amd64-gnu-tdep.h"
+#include "glibc-tdep.h"
+
+extern "C"
+{
+#include 
+}
+
+/* Recognizing signal handler frames.  */
+
+/* When the GNU/Hurd libc calls a signal handler, the return address points
+   inside the trampoline assembly snippet.
+
+   If the trampoline function name can not be identified, we resort to reading
+   memory from the process in order to identify it.  */
+
+static const gdb_byte gnu_sigtramp_code[] =
+{
+/* rpc_wait_trampoline: */
+  0x48, 0xc7, 0xc0, 0xe7, 0xff, 0xff, 0xff,/* mov$-25,%rax */
+  0x0f, 0x05,  /* syscall */
+  0x49, 0x89, 0x04, 0x24,  /* mov%rax,(%r12) */
+  0x48, 0x89, 0xdc,/* mov%rbx,%rsp */
+
+/* trampoline: */
+  0x5f,/* pop%rdi */
+  0x5e,/* pop%rsi */
+  0x5a,/* pop%rdx */
+  0x48, 0x83, 0xc4, 0x08,  /* add$0x8,%rsp */
+  0x41, 0xff, 0xd5,

[PATCH] Port GDB to Hurd x86_64.

2024-02-12 Thread Flavio Cruz
This port extends the existing i686 port to support x86_64 by trying to
reuse existing code whenever it makes sense.

* gdb/amd64-gnu-tdep.c: Adds logic for handling signal frames and
  position of amd64 registers in the different Hurd structs, including
  i386_thread_state. The signal code is very similar to i686, except the
  trampoline code is adapted.
* gdb/amd64-gnu-tdep.h: export register offsets for x86-gnu-nat.c.
* gdb/config/i386/nm-i386gnu.h: renamed to gdb/config/i386/nm-x86-gnu.h
  and adapt it for x86_64.
* gdb/config/i386/i386gnu.mn: renamed to gdb/config/i386/nm-x86-gnu.mn
  and reuse it for x86_64.
* gdb/configure.host: recognize gnu64 as a host.
* gdb/configure.nat: recognize gnu64 host and update existing i386gnu to
  reuse the new shared files.
* gdb/configure.tgt: recognize x86_64-*-gnu* triplet and use
  amd64-gnu-tdep.c.
* gdb/i386-gnu-tdep.c: added i386_gnu_thread_state_reg_offset that is
  copied from i386-gnu-nat.c. This makes it similar to amd64.
* gdb/i386-gnu-tdep.h: export register offsets and number of registers.
* gdb/i386-gnu-nat.c: rename it to x86-gnu-nat.c since we reuse this for
  i386 and amd64. Updated REG_ADDR to use one of the structures. Added
  VALID_REGISTER to make sure it's a register we can provide at this time
  (not all of them are available in amd64). FLAGS_REGISTER is either rfl
  or efl depending on the arch. Renamed functions and class from i386 to x86
  whenever they can be reused.

Tested on Hurd x86_64 and i686.
---

For Hurd x86_64 to work, "[PATCH] Hurd port: update interface to match 
upstream and fix warnings" needs to be applied too.

 gdb/amd64-gnu-tdep.c  | 256 ++
 gdb/amd64-gnu-tdep.h  |  29 ++
 .../i386/{nm-i386gnu.h => nm-x86-gnu.h}   |   7 +
 gdb/config/i386/{i386gnu.mn => x86-gnu.mn}|   0
 gdb/configure.host|   1 +
 gdb/configure.nat |  27 +-
 gdb/configure.tgt |   4 +
 gdb/i386-gnu-tdep.c   |  37 ++-
 gdb/i386-gnu-tdep.h   |  29 ++
 gdb/{i386-gnu-nat.c => x86-gnu-nat.c} | 128 +
 10 files changed, 457 insertions(+), 61 deletions(-)
 create mode 100644 gdb/amd64-gnu-tdep.c
 create mode 100644 gdb/amd64-gnu-tdep.h
 rename gdb/config/i386/{nm-i386gnu.h => nm-x86-gnu.h} (83%)
 rename gdb/config/i386/{i386gnu.mn => x86-gnu.mn} (100%)
 create mode 100644 gdb/i386-gnu-tdep.h
 rename gdb/{i386-gnu-nat.c => x86-gnu-nat.c} (75%)

diff --git a/gdb/amd64-gnu-tdep.c b/gdb/amd64-gnu-tdep.c
new file mode 100644
index 000..57aeccea8b9
--- /dev/null
+++ b/gdb/amd64-gnu-tdep.c
@@ -0,0 +1,256 @@
+/* Target-dependent code for the GNU Hurd.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see .  */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "osabi.h"
+#include "solib-svr4.h"
+
+#include "amd64-tdep.h"
+#include "amd64-gnu-tdep.h"
+
+extern "C"
+{
+#include 
+}
+
+/* Recognizing signal handler frames.  */
+
+/* When the GNU/Hurd libc calls a signal handler, the return address points
+   inside the trampoline assembly snippet.
+
+   If the trampoline function name can not be identified, we resort to reading
+   memory from the process in order to identify it.  */
+
+static const gdb_byte gnu_sigtramp_code[] =
+{
+/* rpc_wait_trampoline: */
+  0x48, 0xc7, 0xc0, 0xe7, 0xff, 0xff, 0xff,/* mov$-25,%rax */
+  0x0f, 0x05,  /* syscall */
+  0x49, 0x89, 0x04, 0x24,  /* mov%rax,(%r12) */
+  0x48, 0x89, 0xdc,/* mov%rbx,%rsp */
+
+/* trampoline: */
+  0x5f,/* pop%rdi */
+  0x5e,/* pop%rsi */
+  0x5a,/* pop%rdx */
+  0x48, 0x83, 0xc4, 0x08,  /* add$0x8,%rsp */
+  0x41, 0xff, 0xd5,/* call   *%r13 */
+
+/* RA HERE */
+  0x48, 0x8b, 0x7c, 0x24, 0x10,/* mov
0x10(%rsp),%rdi */
+  0xc3,/* ret */
+
+/* firewall: */
+  0xf4,/* hlt */
+};
+
+#define 

[PATCH 2/2] Add thread_set_name RPC.

2024-02-11 Thread Flavio Cruz
Like task_set_name, we use the same size as the task name and will
inherit the task name, whenever it exists. This will be used to
implement pthread_setname_np.
---
 ddb/db_print.c|  9 +
 include/mach/gnumach.defs |  8 
 kern/thread.c | 20 
 kern/thread.h |  8 
 4 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/ddb/db_print.c b/ddb/db_print.c
index c8d85d2..f08dd6c 100644
--- a/ddb/db_print.c
+++ b/ddb/db_print.c
@@ -222,10 +222,11 @@ db_print_thread(
}
} else {
if (flag & OPTION_INDENT)
-   db_printf("%3d (%0*X) ", thread_id,
- 2*sizeof(vm_offset_t), thread);
-   else
-   db_printf("(%0*X) ", 2*sizeof(vm_offset_t), thread);
+   db_printf("%3d ", thread_id);
+   if (thread->name[0] &&
+   strncmp (thread->name, thread->task->name, THREAD_NAME_SIZE))
+   db_printf("%s ", thread->name);
+   db_printf("(%0*X) ", 2*sizeof(vm_offset_t), thread);
char status[8];
db_printf("%s", db_thread_stat(thread, status));
if (thread->state & TH_SWAPPED) {
diff --git a/include/mach/gnumach.defs b/include/mach/gnumach.defs
index 6252de9..7ecf74d 100644
--- a/include/mach/gnumach.defs
+++ b/include/mach/gnumach.defs
@@ -207,3 +207,11 @@ routine vm_pages_phys(
vaddr   : vm_address_t;
size: vm_size_t;
out pages   : rpc_phys_addr_array_t);
+
+/*
+ * Set the name of thread THREAD to NAME.  This is a debugging aid.
+ * NAME will be used in error messages printed by the kernel.
+ */
+simpleroutine thread_set_name(
+   thread  : thread_t;
+   name: kernel_debug_name_t);
diff --git a/kern/thread.c b/kern/thread.c
index 23ee8b0..2eab1ca 100644
--- a/kern/thread.c
+++ b/kern/thread.c
@@ -46,6 +46,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -551,6 +552,10 @@ kern_return_t thread_create(
 #endif /* MACH_PCSAMPLE */
 
new_thread->pc_sample.buffer = 0;
+
+   /* Inherit the task name as the thread name. */
+   memcpy (new_thread->name, parent_task->name, THREAD_NAME_SIZE);
+
/*
 *  Add the thread to the task`s list of threads.
 *  The new thread holds another reference to the task.
@@ -2624,3 +2629,18 @@ thread_stats(void)
printf("%d using rpc_reply.\n", rpcreply);
 }
 #endif /* MACH_DEBUG */
+
+/*
+ * thread_set_name
+ *
+ * Set the name of thread THREAD to NAME.
+ */
+kern_return_t
+thread_set_name(
+   thread_tthread,
+   const_kernel_debug_name_t   name)
+{
+   strncpy(thread->name, name, sizeof thread->name - 1);
+   thread->name[sizeof thread->name - 1] = '\0';
+   return KERN_SUCCESS;
+}
diff --git a/kern/thread.h b/kern/thread.h
index 7bfe2e8..21b2503 100644
--- a/kern/thread.h
+++ b/kern/thread.h
@@ -54,6 +54,12 @@
 #include 
 #include 
 
+/*
+ * Thread name buffer size. Use the same size as the task so
+ * the thread can inherit the task's name.
+ */
+#define THREAD_NAME_SIZE TASK_NAME_SIZE
+
 struct thread {
/* Run queues */
queue_chain_t   links;  /* current run queue links */
@@ -232,6 +238,8 @@ struct thread {
 #ifMACH_LOCK_MON
unsigned lock_stack;
 #endif
+
+   charname[THREAD_NAME_SIZE];
 };
 
 #include 
-- 
2.39.2




[PATCH 1/2] Replace kernel header includes in include/mach/mach_types.h with forward declarations.

2024-02-11 Thread Flavio Cruz
I was trying to reuse TASK_NAME_SIZE in kern/thread.h but it was
impossible because files included from kern/task.h end up requiring
kern/thread.h (through percpu.h), creating a recursive dependency.

With this change, mach_types.h only defines forward declarations and
modules have to explicitly include the appropriate header file if they
want to be able touch those structures. Most of the other includes are
required because we no longer grab many different includes through
mach_types.h.
---
 ddb/db_examine.c  |  1 +
 device/io_req.h   |  1 +
 i386/i386/machine_task.c  |  1 +
 i386/i386/percpu.h|  2 +-
 i386/i386/trap.h  |  1 +
 i386/i386at/int_init.c|  1 +
 include/mach/mach_types.h | 13 ++---
 include/mach/std_types.h  |  4 
 ipc/ipc_space.h   |  1 +
 kern/eventcount.h |  2 ++
 kern/ipc_mig.h|  1 +
 kern/thread.c |  4 
 12 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/ddb/db_examine.c b/ddb/db_examine.c
index 88d7a57..1941fc3 100644
--- a/ddb/db_examine.c
+++ b/ddb/db_examine.c
@@ -47,6 +47,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define db_thread_to_task(thread)  ((thread)? thread->task: TASK_NULL)
 
diff --git a/device/io_req.h b/device/io_req.h
index e66e080..fb63696 100644
--- a/device/io_req.h
+++ b/device/io_req.h
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
diff --git a/i386/i386/machine_task.c b/i386/i386/machine_task.c
index d592838..8bebf36 100644
--- a/i386/i386/machine_task.c
+++ b/i386/i386/machine_task.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
diff --git a/i386/i386/percpu.h b/i386/i386/percpu.h
index 86b0a31..637d2ca 100644
--- a/i386/i386/percpu.h
+++ b/i386/i386/percpu.h
@@ -66,7 +66,7 @@ MACRO_END
 #endif
 
 #include 
-#include 
+#include 
 
 struct percpu {
 struct percpu  *self;
diff --git a/i386/i386/trap.h b/i386/i386/trap.h
index e82164d..db22273 100644
--- a/i386/i386/trap.h
+++ b/i386/i386/trap.h
@@ -30,6 +30,7 @@
 #include 
 
 #ifndef __ASSEMBLER__
+#include 
 #include 
 
 char *trap_name(unsigned int trapnum);
diff --git a/i386/i386at/int_init.c b/i386/i386at/int_init.c
index 262bef1..5c8fce6 100644
--- a/i386/i386at/int_init.c
+++ b/i386/i386at/int_init.c
@@ -23,6 +23,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #ifdef APIC
diff --git a/include/mach/mach_types.h b/include/mach/mach_types.h
index 57f8f22..5ecd686 100644
--- a/include/mach/mach_types.h
+++ b/include/mach/mach_types.h
@@ -57,13 +57,12 @@
 #include 
 
 #ifdef MACH_KERNEL
-#include  /* for task_array_t */
-#include/* for thread_array_t */
-#include /* for processor_array_t,
-  processor_set_array_t,
-  processor_set_name_array_t */
-#include 
-   /* for emulation_vector_t */
+
+typedef struct task*task_t;
+typedef struct thread  *thread_t;
+typedef struct processor   *processor_t;
+typedef struct processor_set   *processor_set_t;
+
 #else  /* MACH_KERNEL */
 typedefmach_port_t task_t;
 typedef task_t *task_array_t;
diff --git a/include/mach/std_types.h b/include/mach/std_types.h
index f78e236..0d5db0a 100644
--- a/include/mach/std_types.h
+++ b/include/mach/std_types.h
@@ -41,8 +41,4 @@
 typedefvm_offset_t pointer_t;
 typedefvm_offset_t vm_address_t;
 
-#ifdef MACH_KERNEL
-#include 
-#endif /* MACH_KERNEL */
-
 #endif /* _MACH_STD_TYPES_H_ */
diff --git a/ipc/ipc_space.h b/ipc/ipc_space.h
index 3f0eaa0..96d5894 100644
--- a/ipc/ipc_space.h
+++ b/ipc/ipc_space.h
@@ -49,6 +49,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /*
diff --git a/kern/eventcount.h b/kern/eventcount.h
index 7cc8220..598d7e0 100644
--- a/kern/eventcount.h
+++ b/kern/eventcount.h
@@ -35,6 +35,8 @@
 #ifndef_KERN_EVENTCOUNT_H_
 #define_KERN_EVENTCOUNT_H_ 1
 
+#include 
+
 /* kernel visible only */
 
 typedef struct evc {
diff --git a/kern/ipc_mig.h b/kern/ipc_mig.h
index a8ee786..422e8d8 100644
--- a/kern/ipc_mig.h
+++ b/kern/ipc_mig.h
@@ -28,6 +28,7 @@
 
 #include 
 #include 
+#include 
 
 /*
  *  Routine:mach_msg_send_from_kernel
diff --git a/kern/thread.c b/kern/thread.c
index de9d198..23ee8b0 100644
--- a/kern/thread.c
+++ b/kern/thread.c
@@ -32,12 +32,15 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -59,6 +62,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
-- 
2.39.2




[PATCH] Hurd port: update interface to match upstream and fix warnings.

2024-02-06 Thread Flavio Cruz
We have recently updated the interface for raising exceptions to use
long [1] and updated mach_port_t to be "unsigned int". This patches fixes
those problems and will help us port GDB to Hurd x86_64.

Tested on Hurd i686 and x86_64.

[1] 
https://git.savannah.gnu.org/cgit/hurd/gnumach.git/tree/include/mach/exc.defs
---
 gdb/exc_request.defs |  2 +-
 gdb/gnu-nat.c| 37 +++--
 2 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/gdb/exc_request.defs b/gdb/exc_request.defs
index 9b5ed2ee421..0291e7b30f1 100644
--- a/gdb/exc_request.defs
+++ b/gdb/exc_request.defs
@@ -48,4 +48,4 @@ simpleroutine exception_raise_request (
task: mach_port_t;
exception   : integer_t;
code: integer_t;
-   subcode : integer_t);
+   subcode : rpc_long_integer_t);
diff --git a/gdb/gnu-nat.c b/gdb/gnu-nat.c
index 0add13e3b89..aba1034396f 100644
--- a/gdb/gnu-nat.c
+++ b/gdb/gnu-nat.c
@@ -134,7 +134,8 @@ static struct inf *make_inf ();
 struct exc_state
   {
 int exception; /* The exception code.  */
-int code, subcode;
+int code;
+long subcode;
 mach_port_t handler;   /* The real exception port to handle this.  */
 mach_port_t reply; /* The reply port from the exception call.  */
   };
@@ -389,7 +390,7 @@ gnu_nat_target::proc_get_exception_port (struct proc * 
proc, mach_port_t * port)
 kern_return_t
 gnu_nat_target::proc_set_exception_port (struct proc * proc, mach_port_t port)
 {
-  proc_debug (proc, "setting exception port: %lu", port);
+  proc_debug (proc, "setting exception port: %u", port);
   if (proc_is_task (proc))
 return task_set_exception_port (proc->port, port);
   else
@@ -429,7 +430,7 @@ gnu_nat_target::proc_steal_exc_port (struct proc *proc, 
mach_port_t exc_port)
 {
   kern_return_t err = 0;
 
-  proc_debug (proc, "inserting exception port: %lu", exc_port);
+  proc_debug (proc, "inserting exception port: %u", exc_port);
 
   if (cur_exc_port != exc_port)
/* Put in our exception port.  */
@@ -450,7 +451,7 @@ gnu_nat_target::proc_steal_exc_port (struct proc *proc, 
mach_port_t exc_port)
  proc->saved_exc_port = cur_exc_port;
}
 
-  proc_debug (proc, "saved exception port: %lu", proc->saved_exc_port);
+  proc_debug (proc, "saved exception port: %u", proc->saved_exc_port);
 
   if (!err)
proc->exc_port = exc_port;
@@ -562,11 +563,11 @@ gnu_nat_target::make_proc (struct inf *inf, mach_port_t 
port, int tid)
MACH_MSG_TYPE_MAKE_SEND_ONCE,
_port);
   if (err)
-warning (_("Couldn't request notification for port %lu: %s"),
+warning (_("Couldn't request notification for port %u: %s"),
 port, safe_strerror (err));
   else
 {
-  proc_debug (proc, "notifications to: %lu", inf->event_port);
+  proc_debug (proc, "notifications to: %u", inf->event_port);
   if (prev_port != MACH_PORT_NULL)
mach_port_deallocate (mach_task_self (), prev_port);
 }
@@ -741,7 +742,7 @@ gnu_nat_target::inf_set_pid (struct inf *inf, pid_t pid)
   pid, safe_strerror (err));
 }
 
-  inf_debug (inf, "setting task: %lu", task_port);
+  inf_debug (inf, "setting task: %u", task_port);
 
   if (inf->pause_sc)
 task_suspend (task_port);
@@ -1072,7 +1073,7 @@ gnu_nat_target::inf_validate_procs (struct inf *inf)
else
  inf->threads = thread;
last = thread;
-   proc_debug (thread, "new thread: %lu", threads[i]);
+   proc_debug (thread, "new thread: %u", threads[i]);
 
ptid = ptid_t (inf->pid, thread->tid, 0);
 
@@ -1337,8 +1338,8 @@ gnu_nat_target::inf_signal (struct inf *inf, enum 
gdb_signal sig)
  struct exc_state *e = >exc;
 
  inf_debug (inf, "passing through exception:"
-" task = %lu, thread = %lu, exc = %d"
-", code = %d, subcode = %d",
+" task = %u, thread = %u, exc = %d"
+", code = %d, subcode = %ld",
 w->thread->port, inf->task->port,
 e->exception, e->code, e->subcode);
  err =
@@ -1631,13 +1632,13 @@ gnu_nat_target::wait (ptid_t ptid, struct 
target_waitstatus *status,
 kern_return_t
 S_exception_raise_request (mach_port_t port, mach_port_t reply_port,
   thread_t thread_port, task_t task_port,
-  int exception, int code, int subcode)
+  int exception, int code, long subcode)
 {
   struct inf *inf = waiting_inf;
   struct proc *thread = inf_port_to_thread (inf, thread_port);
 
   inf_debug (waiting_inf,
-"thread = %lu, task = %lu, exc = %d, code = %d, subcode = %d",
+"thread = %u, task = %u, exc = %d, code = %d, subcode = %ld",
 thread_port, task_port, exception, code, 

[PATCH binutils-gdb] Port GDB to Hurd x86_64.

2024-02-03 Thread Flavio Cruz
This port extends the existing i686 port to support x86_64 by trying to
reuse existing code whenever it makes sense.

* gdb/amd64-gnu-tdep.c: Adds logic for handling signal frames and
  position of amd64 registers in the different Hurd structs, including
  i386_thread_state. The signal code is very similar to i686, except the
  trampoline code is adapted.
* gdb/amd64-gnu-tdep.h: export register offsets for x86-gnu-nat.c.
* gdb/config/i386/nm-i386gnu.h: renamed to gdb/config/i386/nm-x86-gnu.h
  and adapt it for x86_64.
* gdb/config/i386/i386gnu.mn: renamed to gdb/config/i386/nm-x86-gnu.mn
  and reuse it for x86_64.
* gdb/configure.host: recognize gnu64 as a host.
* gdb/configure.nat: recognize gnu64 host and update existing i386gnu to
  reuse the new shared files.
* gdb/configure.tgt: recognize x86_64-*-gnu* triplet and use
  amd64-gnu-tdep.c.
* gdb/exc_request.defs: update subcode to have type rpc_long_integer_t
  to match the definition upstream, otherwise we get a type error.
* gdb/gnu-nat.c: update subcode type for long and update printf
  modifiers for ports (now unsigned int) and subcode.
* gdb/i386-gnu-tdep.c: added i386_gnu_thread_state_reg_offset that is
  copied from i386-gnu-nat.c. This makes it similar to amd64.
* gdb/i386-gnu-tdep.h: export register offsets and number of registers.
* gdb/i386-gnu-nat.c: rename it to x86-gnu-nat.c since we reuse this for
  i386 and amd64. Updated REG_ADDR to use one of the structures. Added
  VALID_REGISTER to make sure it's a register we can provide at this time
  (not all of them are available in amd64). FLAGS_REGISTER is either rfl
  or efl depending on the arch. Renamed functions and class from i386 to x86
  whenever they can be reused.
---

Testing: I have tried to step through some basic programs and overall it
seems to work. The part I am less confident of is the signal handling, I
am still trying to see how I can test it.

 gdb/amd64-gnu-tdep.c  | 253 ++
 gdb/amd64-gnu-tdep.h  |  29 ++
 .../i386/{nm-i386gnu.h => nm-x86-gnu.h}   |   7 +
 gdb/config/i386/{i386gnu.mn => x86-gnu.mn}|   0
 gdb/configure.host|   1 +
 gdb/configure.nat |  27 +-
 gdb/configure.tgt |   4 +
 gdb/exc_request.defs  |   2 +-
 gdb/gnu-nat.c |  37 +--
 gdb/i386-gnu-tdep.c   |  34 +++
 gdb/i386-gnu-tdep.h   |  29 ++
 gdb/{i386-gnu-nat.c => x86-gnu-nat.c} | 128 +
 12 files changed, 473 insertions(+), 78 deletions(-)
 create mode 100644 gdb/amd64-gnu-tdep.c
 create mode 100644 gdb/amd64-gnu-tdep.h
 rename gdb/config/i386/{nm-i386gnu.h => nm-x86-gnu.h} (83%)
 rename gdb/config/i386/{i386gnu.mn => x86-gnu.mn} (100%)
 create mode 100644 gdb/i386-gnu-tdep.h
 rename gdb/{i386-gnu-nat.c => x86-gnu-nat.c} (75%)

diff --git a/gdb/amd64-gnu-tdep.c b/gdb/amd64-gnu-tdep.c
new file mode 100644
index 000..ff1db5c76bb
--- /dev/null
+++ b/gdb/amd64-gnu-tdep.c
@@ -0,0 +1,253 @@
+/* Target-dependent code for the GNU Hurd.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see .  */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "osabi.h"
+#include "solib-svr4.h"
+
+#include "amd64-tdep.h"
+#include "amd64-gnu-tdep.h"
+
+extern "C"
+{
+#include 
+}
+
+/* Recognizing signal handler frames.  */
+
+/* When the GNU/Hurd libc calls a signal handler, the return address points
+   inside the trampoline assembly snippet.
+
+   If the trampoline function name can not be identified, we resort to reading
+   memory from the process in order to identify it.  */
+
+static const gdb_byte gnu_sigtramp_code[] =
+{
+/* rpc_wait_trampoline: */
+  0x48, 0xc7, 0xc0, 0xe7, 0xff, 0xff, 0xff,/* mov$-25,%rax */
+  0x0f, 0x05,  /* syscall */
+  0x49, 0x89, 0x04, 0x24,  /* mov%rax,(%r12) */
+
+/* trampoline: */
+  0x5f,/* pop%rdi */
+  0x5e,/* pop%rsi */
+  0x5a,/* pop%rdx */
+  0x48, 0x83, 0xc4, 0x08,  /* add$0x8,%rsp */
+  0x41, 

[PATCH hurd] Update rpctrace to use the new ABI for inlined port names

2024-01-21 Thread Flavio Cruz
---
 utils/rpctrace.c | 83 +++-
 1 file changed, 53 insertions(+), 30 deletions(-)

diff --git a/utils/rpctrace.c b/utils/rpctrace.c
index f7046a0..c8635a3 100644
--- a/utils/rpctrace.c
+++ b/utils/rpctrace.c
@@ -801,6 +801,18 @@ rewrite_right (mach_port_t *right, mach_msg_type_name_t 
*type,
   return 0;
 }
 
+static mach_port_name_t *
+get_port_ref (void *data, const boolean_t is_inline, const int i) {
+  if (is_inline)
+{
+  mach_port_name_inlined_t *const inlined_port_names = data;
+  return _port_names[i].name;
+} else {
+  mach_port_t *const portnames = data;
+  return [i];
+}
+}
+
 static void
 print_contents (mach_msg_header_t *inp,
void *msg_buf_ptr, struct req_info *req)
@@ -818,6 +830,7 @@ print_contents (mach_msg_header_t *inp,
   mach_msg_type_number_t nelt; /* Number of data items.  */
   mach_msg_type_size_t eltsize; /* Bytes per item.  */
   mach_msg_type_name_t name; /* MACH_MSG_TYPE_* code */
+  boolean_t is_inline = type->msgt_inline;
 
   if (!type->msgt_longform)
{
@@ -834,7 +847,7 @@ print_contents (mach_msg_header_t *inp,
  data = msg_buf_ptr = lt + 1;
}
 
-  if (!type->msgt_inline)
+  if (!is_inline)
{
  /* This datum is out-of-line, meaning the message actually
 contains a pointer to a vm_allocate'd region of data.  */
@@ -857,35 +870,39 @@ print_contents (mach_msg_header_t *inp,
   if (MACH_MSG_TYPE_PORT_ANY_RIGHT (name))
{
  /* These are port rights.  Translate them into wrappers.  */
- mach_port_t *const portnames = data;
  mach_msg_type_number_t i;
  mach_msg_type_name_t newtypes[nelt ? : 1];
  int poly;
 
  assert_backtrace (inp->msgh_bits & MACH_MSGH_BITS_COMPLEX);
- assert_backtrace (eltsize == sizeof (mach_port_t));
+
+ if (is_inline)
+   assert_backtrace (eltsize == sizeof (mach_port_name_inlined_t));
+ else
+   assert_backtrace (eltsize == sizeof (mach_port_t));
 
  poly = 0;
  for (i = 0; i < nelt; ++i)
{
  char *str;
+ mach_port_name_t *port_name = get_port_ref (data, is_inline, i);
 
  newtypes[i] = name;
 
- str = rewrite_right ([i], [i], req);
+ str = rewrite_right (port_name, [i], req);
 
  putc ((i == 0 && nelt > 1) ? '{' : ' ', ostream);
 
- if (portnames[i] == MACH_PORT_NULL)
+ if (*port_name == MACH_PORT_NULL)
fprintf (ostream, "(null)");
- else if (portnames[i] == MACH_PORT_DEAD)
+ else if (*port_name == MACH_PORT_DEAD)
fprintf (ostream, "(dead)");
  else
{
  if (str != 0)
fprintf (ostream, "%s", str);
  else
-   fprintf (ostream, "%3u", (unsigned int) portnames[i]);
+   fprintf (ostream, "%3u", (unsigned int) *port_name);
}
  if (i > 0 && newtypes[i] != newtypes[0])
poly = 1;
@@ -900,39 +917,45 @@ print_contents (mach_msg_header_t *inp,
  /* Some of the new rights are MAKE_SEND_ONCE.
 Turn them all into MOVE_SEND_ONCE.  */
  for (i = 0; i < nelt; ++i)
-   if (newtypes[i] == MACH_MSG_TYPE_MAKE_SEND_ONCE)
+   {
+ mach_port_name_t *port_name = get_port_ref (data, 
is_inline, i);
+ if (newtypes[i] == MACH_MSG_TYPE_MAKE_SEND_ONCE)
  {
err = mach_port_insert_right (mach_task_self (),
- portnames[i],
- portnames[i],
- newtypes[i]);
+   *port_name,
+   *port_name,
+   newtypes[i]);
assert_perror_backtrace (err);
  }
-   else
- assert_backtrace (newtypes[i] == 
MACH_MSG_TYPE_MOVE_SEND_ONCE);
+ else
+   assert_backtrace (newtypes[i] == 
MACH_MSG_TYPE_MOVE_SEND_ONCE);
+   }
}
  else
{
  for (i = 0; i < nelt; ++i)
-   switch (newtypes[i])
+   {
+ mach_port_name_t *port_name = get_port_ref (data, 
is_inline, i);
+ switch (newtypes[i])
  {
- case MACH_MSG_TYPE_COPY_SEND:
-   err = mach_port_mod_refs (mach_task_self (),
- portnames[i],
- MACH_PORT_RIGHT_SEND, +1);
- 

[PATCH hurd 5/6] ftpfs: use correct function signature for interrupt_check

2024-01-21 Thread Flavio Cruz
---
 ftpfs/ftpfs.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/ftpfs/ftpfs.c b/ftpfs/ftpfs.c
index 794439b..9310a56 100644
--- a/ftpfs/ftpfs.c
+++ b/ftpfs/ftpfs.c
@@ -51,8 +51,13 @@ struct ftpfs *ftpfs;
 /* Parameters describing the server we're connecting to.  */
 struct ftp_conn_params *ftpfs_ftp_params = 0;
 
+static int
+ftp_hooks_interrupt_check (struct ftp_conn *) {
+  return ports_self_interrupted ();
+}
+
 /* customization hooks.  */
-struct ftp_conn_hooks ftpfs_ftp_hooks = { interrupt_check: 
ports_self_interrupted };
+struct ftp_conn_hooks ftpfs_ftp_hooks = { interrupt_check: 
ftp_hooks_interrupt_check };
 
 /* The (user-specified) name of the SERVER:FILESYSTEM we're connected too.  */
 char *ftpfs_remote_fs;
-- 
2.39.2




[PATCH hurd 6/6] hurdio: use correct function signature for hurdio_mdmstate

2024-01-21 Thread Flavio Cruz
---
 term/hurdio.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/term/hurdio.c b/term/hurdio.c
index c6e14a4..a3e2a0a 100644
--- a/term/hurdio.c
+++ b/term/hurdio.c
@@ -613,8 +613,8 @@ hurdio_mdmctl (int how, int bits)
 }
 
 
-static int
-hurdio_mdmstate (void)
+static error_t
+hurdio_mdmstate (int *state)
 {
   int oldbits;
 
-- 
2.39.2




[PATCH hurd 2/6] procfs: remove unused rootdir_symlink_make_node

2024-01-21 Thread Flavio Cruz
Not needed since b2c97e251bb470e6f967c716081675a96dbde59c
---
 procfs/rootdir.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/procfs/rootdir.c b/procfs/rootdir.c
index 7742edd..206a541 100644
--- a/procfs/rootdir.c
+++ b/procfs/rootdir.c
@@ -706,14 +706,6 @@ rootdir_file_make_node (void *dir_hook, const void 
*entry_hook)
   return procfs_make_node (entry_hook, dir_hook);
 }
 
-static struct node *
-rootdir_symlink_make_node (void *dir_hook, const void *entry_hook)
-{
-  struct node *np = procfs_make_node (entry_hook, dir_hook);
-  if (np)
-procfs_node_chtype (np, S_IFLNK);
-  return np;
-}
 
 /* Translator linkage.  */
 
-- 
2.39.2




[PATCH hurd 3/6] Fix warnings in fstests

2024-01-21 Thread Flavio Cruz
---
 fstests/fstests.c   |  1 -
 fstests/timertest.c | 10 --
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/fstests/fstests.c b/fstests/fstests.c
index b776503..ca60203 100644
--- a/fstests/fstests.c
+++ b/fstests/fstests.c
@@ -94,7 +94,6 @@ main (void)
 #endif
 
   printf ("All done.\n");
-  malloc (0);
 
   return 0;
 }
diff --git a/fstests/timertest.c b/fstests/timertest.c
index 2d60256..6eca98e 100644
--- a/fstests/timertest.c
+++ b/fstests/timertest.c
@@ -32,14 +32,20 @@ alarm_handler (int signo)
 int
 main(int argc, char *argv[])
 {
+  struct sigaction alarm_sigaction = { 0 };
+  sigset_t empty_sigset;
   struct itimerval real_timer;
 
+  sigemptyset (_sigset);
+
   real_timer.it_interval.tv_usec = 0;
   real_timer.it_interval.tv_sec = 1;
   real_timer.it_value.tv_usec = 0;
   real_timer.it_value.tv_sec = 1;
 
-  signal (SIGALRM, alarm_handler);
+  alarm_sigaction.sa_handler = _handler;
+  alarm_sigaction.sa_flags = SA_RESTART;
+  sigaction (SIGALRM, _sigaction, NULL);
 
   if (setitimer (ITIMER_REAL, _timer, 0) < 0)
 error (1, errno, "Setting timer");
@@ -56,7 +62,7 @@ main(int argc, char *argv[])
{
  puts ("Saw EOF.  Pausing (no input)...");
  fflush (stdout);
- sigpause (0);
+ sigsuspend (_sigset);
}
   else
printf ("Saw %.3o\n", c);
-- 
2.39.2




[PATCH hurd 4/6] x86_64: do not define mach_cpu_subtypes since we don't use it

2024-01-21 Thread Flavio Cruz
---
 proc/cpu-types.c | 2 ++
 proc/host.c  | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/proc/cpu-types.c b/proc/cpu-types.c
index 3d89d5a..7a814f6 100644
--- a/proc/cpu-types.c
+++ b/proc/cpu-types.c
@@ -38,6 +38,7 @@ const char *const mach_cpu_types[] =
 #endif
   };
 
+#ifndef __x86_64__
 const char *const mach_cpu_subtypes[][32] =
   {
 [CPU_TYPE_VAX] =
@@ -167,3 +168,4 @@ const char *const mach_cpu_subtypes[][32] =
[CPU_SUBTYPE_ALPHA_21064] = "ALPHA_21064",
   },
   };
+#endif  /* !__x86_64__ */
diff --git a/proc/host.c b/proc/host.c
index 823bda5..c2b53c3 100644
--- a/proc/host.c
+++ b/proc/host.c
@@ -340,7 +340,9 @@ void
 initialize_version_info (void)
 {
   extern const char *const mach_cpu_types[];
+#ifndef __x86_64__
   extern const char *const mach_cpu_subtypes[][32];
+#endif
   kernel_version_t kv;
   char *p;
   struct host_basic_info info;
-- 
2.39.2




[PATCH hurd 1/6] Restructure argument setup in hashbang

2024-01-21 Thread Flavio Cruz
We do a few things here:
- Move search_path to the scope where it is used to make dependencies
  more clear.
- Have a separate variable to store the file name we eventually need to
  free and move the free logic to happen in a single place.

Both of this allows us to still free the name even if a fault is generated and
also avoids a compiler warning as we try to assign a 'const char*'
file_name_exec to a 'char *', making it more clear to what exactly we
need to free. I also believe 'error' in line 245 was not initialized in
case 'file_name_exec' is used and this fixes that too.
---
 exec/hashexec.c | 91 +++--
 1 file changed, 43 insertions(+), 48 deletions(-)

diff --git a/exec/hashexec.c b/exec/hashexec.c
index a107291..0953679 100644
--- a/exec/hashexec.c
+++ b/exec/hashexec.c
@@ -221,14 +221,14 @@ check_hashbang (struct execdata *e,
 
   if (! e->error)
 {
-  int free_file_name = 0; /* True if we should free FILE_NAME.  */
+  char * volatile file_name_to_free = NULL; /* Will free this if set.  */
   jmp_buf args_faulted;
   void fault_handler (int signo)
{ longjmp (args_faulted, 1); }
   error_t setup_args (struct hurd_signal_preemptor *preemptor)
{
  size_t namelen;
- char * volatile file_name = NULL;
+ const char * volatile file_name = NULL;
 
  if (setjmp (args_faulted))
file_name = NULL;
@@ -242,44 +242,42 @@ check_hashbang (struct execdata *e,
 named by ARGV[0] in the `PATH' environment variable
 might find it.  */
 
- error_t error;
- char *name;
- int free_name = 0; /* True if we should free NAME. */
- file_t name_file;
- mach_port_t fileid, filefsid;
- ino_t fileno;
-
- /* Search $PATH for NAME, opening a port NAME_FILE on it.
-This is encapsulated in a function so we can catch faults
-reading the user's environment.  */
- error_t search_path (struct hurd_signal_preemptor *preemptor)
+ if (file_name_exec && file_name_exec[0] != '\0')
+   file_name = file_name_exec;
+ else
{
- error_t err;
- char *path = envz_get (envp, envplen, "PATH"), *pfxed_name;
-
- if (! path)
+ error_t error;
+ file_t name_file;
+ mach_port_t fileid, filefsid;
+ ino_t fileno;
+ char *name;
+ /* Search $PATH for NAME, opening a port NAME_FILE on it.
+This is encapsulated in a function so we can catch faults
+reading the user's environment.  */
+ error_t search_path (struct hurd_signal_preemptor *preemptor)
{
- const size_t len = confstr (_CS_PATH, NULL, 0);
- path = alloca (len);
- confstr (_CS_PATH, path, len);
-   }
+ error_t err;
+ char *path = envz_get (envp, envplen, "PATH"), 
*pfxed_name;
 
- err = hurd_file_name_path_lookup (user_port, user_fd, 0,
-   name, path, O_EXEC, 0,
-   _file, _name);
- if (!err && pfxed_name)
-   {
- name = pfxed_name;
- free_name = 1;
-   }
+ if (! path)
+   {
+ const size_t len = confstr (_CS_PATH, NULL, 0);
+ path = alloca (len);
+ confstr (_CS_PATH, path, len);
+   }
 
- return err;
-   }
+ err = hurd_file_name_path_lookup (user_port, user_fd, 0,
+   name, path, O_EXEC, 0,
+   _file, 
_name);
+ if (!err && pfxed_name)
+   {
+ name = pfxed_name;
+ file_name_to_free = pfxed_name;
+   }
+
+ return err;
+   }
 
- if (file_name_exec && file_name_exec[0] != '\0')
-   name = file_name_exec;
- else
-   {
  /* Try to locate the file.  */
  error = io_identity (file, , , );
  if (error)
@@ -320,15 +318,10 @@ check_hashbang (struct execdata *e,
}
 
  mach_port_deallocate (mach_task_self (), fileid);
-   }
 
- if (!error)
-   {
- file_name = name;
- free_file_name = free_name;
+ if (!error)
+ 

[PATCH hurd] x86_64: utmp uses int32_t to store time so use a temporary variable

2023-12-30 Thread Flavio Cruz
---
 utils/login.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/utils/login.c b/utils/login.c
index 3134c4a..334941c 100644
--- a/utils/login.c
+++ b/utils/login.c
@@ -157,12 +157,17 @@ static void
 add_utmp_entry (char *args, unsigned args_len, int inherit_host)
 {
   struct utmp utmp;
+  struct timeval current_time;
   char const *host = 0;
   long addr = 0;
 
   memset (, 0, sizeof(utmp));
 
-  gettimeofday (_tv, 0);
+  gettimeofday (_time, NULL);
+  /* For x86_64, sizeof(utmp.ut_tv) != sizeof(struct timeval) */
+  utmp.ut_tv.tv_sec = current_time.tv_sec;
+  utmp.ut_tv.tv_usec = current_time.tv_usec;
+
   strncpy (utmp.ut_name, envz_get (args, args_len, "USER") ?: "",
   sizeof (utmp.ut_name));
 
-- 
2.39.2




[PATCH hurd 06/11] x86_64: use 21 bytes in libps since %z might require more characters.

2023-12-29 Thread Flavio Cruz
This makes GCC happy.
---
 libps/spec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libps/spec.c b/libps/spec.c
index dec5704..9f64703 100644
--- a/libps/spec.c
+++ b/libps/spec.c
@@ -492,7 +492,7 @@ error_t
 ps_emit_nice_size_t (struct proc_stat *ps, struct ps_fmt_field *field,
 struct ps_stream *stream)
 {
-  char buf[20];
+  char buf[21];
   size_t value = FG_PROC_STAT (field, size_t)(ps);
   char *sfx = " KMG";
   size_t frac = 0;
-- 
2.39.2




[PATCH hurd 11/11] pfinet: fix type alias

2023-12-29 Thread Flavio Cruz
---
 pfinet/stubs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pfinet/stubs.c b/pfinet/stubs.c
index 9affcff..01ba2fa 100644
--- a/pfinet/stubs.c
+++ b/pfinet/stubs.c
@@ -50,7 +50,7 @@ void dev_activate (struct device *)
  __attribute__ ((alias ("dev_init_scheduler")));
 void dev_deactivate (struct device *)
  __attribute__ ((alias ("dev_init_scheduler")));
-void tcp_ioctl (void) __attribute__ ((alias ("dev_init_scheduler")));
+void tcp_ioctl (struct device *) __attribute__ ((alias 
("dev_init_scheduler")));
 
 /* This isn't quite a stub, but it's not quite right either.  */
 __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr,
-- 
2.39.2




[PATCH hurd 03/11] Use mach_msg_type_number_t whenever required to avoid warnings

2023-12-29 Thread Flavio Cruz
---
 libfshelp-tests/race.c |  9 +
 libnetfs/file-get-translator.c |  2 +-
 pfinet/ethernet.c  |  2 +-
 pfinet/io-ops.c| 10 ++
 utils/mount.c  |  2 +-
 utils/msgport.c|  2 +-
 6 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/libfshelp-tests/race.c b/libfshelp-tests/race.c
index 376ada2..e1df296 100644
--- a/libfshelp-tests/race.c
+++ b/libfshelp-tests/race.c
@@ -33,7 +33,8 @@ int main (int argc, char **argv)
   mach_port_t rendezvous = MACH_PORT_NULL;
   int fd;
   int i;
-  mach_msg_type_number_t v;
+  mach_msg_type_number_t n_read;
+  vm_size_t v;
   int blocked = 0;
   char buf[10] = "";
   char *bufp;
@@ -61,12 +62,12 @@ int main (int argc, char **argv)
   if (err)
 error (1, err, "file_record_lock");
 
-  v = sizeof (buf);
+  v = n_read = sizeof (buf);
   bufp = buf;
-  io_read (fd, , , 0, v);
+  io_read (fd, , _read, 0, v);
 
   v = atoi (bufp);
-  sprintf (buf, "%d\n", v + 1);
+  sprintf (buf, "%d\n", (int) (v + 1));
 
   v = 10;
   io_write (fd, buf, sizeof (buf), 0, );
diff --git a/libnetfs/file-get-translator.c b/libnetfs/file-get-translator.c
index b3998b0..f402250 100644
--- a/libnetfs/file-get-translator.c
+++ b/libnetfs/file-get-translator.c
@@ -116,7 +116,7 @@ netfs_S_file_get_translator (struct protid *user,
   else if (np->nn_translated & S_IPTRANS)
 {
   char *string = NULL;
-  size_t len = 0;
+  mach_msg_type_number_t len = 0;
   err = netfs_get_translator (np, , );
   if (!err)
{
diff --git a/pfinet/ethernet.c b/pfinet/ethernet.c
index ad21917..65ec1e2 100644
--- a/pfinet/ethernet.c
+++ b/pfinet/ethernet.c
@@ -324,7 +324,7 @@ void
 setup_ethernet_device (char *name, struct device **device)
 {
   struct net_status netstat;
-  size_t count;
+  mach_msg_type_number_t count;
   int net_address[2];
   error_t err;
   struct ether_device *edev;
diff --git a/pfinet/io-ops.c b/pfinet/io-ops.c
index 818f113..5f83a02 100644
--- a/pfinet/io-ops.c
+++ b/pfinet/io-ops.c
@@ -135,10 +135,11 @@ S_io_seek (struct sock_user *user,
 
 kern_return_t
 S_io_readable (struct sock_user *user,
-  vm_size_t *amount)
+  vm_size_t *out_amount)
 {
   struct sock *sk;
   error_t err;
+  mach_msg_type_number_t amount = 0;
 
   if (!user)
 return EOPNOTSUPP;
@@ -160,7 +161,8 @@ S_io_readable (struct sock_user *user,
 {
 case SOCK_STREAM:
 case SOCK_SEQPACKET:
-  err = tcp_tiocinq (sk, amount);
+  err = tcp_tiocinq (sk, );
+  *out_amount = amount;
   break;
 
 case SOCK_DGRAM:
@@ -169,7 +171,7 @@ S_io_readable (struct sock_user *user,
err = EINVAL;
   else
/* Boy, I really love the C language. */
-   *amount = (skb_peek (>receive_queue)
+   *out_amount = (skb_peek (>receive_queue)
   ? : &((struct sk_buff){}))->len;
   break;
 
@@ -358,7 +360,7 @@ S_io_reauthenticate (struct sock_user *user,
   struct sock_user *newuser;
   uid_t gubuf[20], ggbuf[20], aubuf[20], agbuf[20];
   uid_t *gen_uids, *gen_gids, *aux_uids, *aux_gids;
-  size_t genuidlen, gengidlen, auxuidlen, auxgidlen;
+  mach_msg_type_number_t genuidlen, gengidlen, auxuidlen, auxgidlen;
   error_t err;
   size_t i, j;
   auth_t auth;
diff --git a/utils/mount.c b/utils/mount.c
index 75211d7..898e056 100644
--- a/utils/mount.c
+++ b/utils/mount.c
@@ -493,7 +493,7 @@ do_query (struct fs *fs)
   error_t err;
   fsys_t fsys;
   char _opts[200], *opts = _opts;
-  size_t opts_len = sizeof opts;
+  mach_msg_type_number_t opts_len = sizeof opts;
   size_t nopts;
 
   err = fs_fsys (fs, );
diff --git a/utils/msgport.c b/utils/msgport.c
index a07cc0e..e3ea430 100644
--- a/utils/msgport.c
+++ b/utils/msgport.c
@@ -676,7 +676,7 @@ main(int argc, char *argv[])
   size_t num_cmds = 0;
   struct cmds_argp_params cmds_argp_params = { , _cmds };
   pid_t *pids = 0;  /* User-specified pids.  */
-  size_t num_pids = 0;
+  mach_msg_type_number_t num_pids = 0;
   struct pids_argp_params pids_argp_params = { , _pids, 0 };
 
   error_t parse_opt (int key, char *arg, struct argp_state *state)
-- 
2.39.2




[PATCH hurd 01/11] Initialize a few error variables to avoid GCC warnings

2023-12-29 Thread Flavio Cruz
---
 ext2fs/pager.c | 2 +-
 fatfs/pager.c  | 2 +-
 trans/random.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/ext2fs/pager.c b/ext2fs/pager.c
index 2869f4d..61db0df 100644
--- a/ext2fs/pager.c
+++ b/ext2fs/pager.c
@@ -170,7 +170,7 @@ static error_t
 file_pager_read_page (struct node *node, vm_offset_t page,
  void **buf, int *writelock)
 {
-  error_t err;
+  error_t err = 0;
   int offs = 0;
   int partial = 0; /* A page truncated by the EOF.  */
   pthread_rwlock_t *lock = NULL;
diff --git a/fatfs/pager.c b/fatfs/pager.c
index 36e7012..efe0203 100644
--- a/fatfs/pager.c
+++ b/fatfs/pager.c
@@ -210,7 +210,7 @@ static error_t
 file_pager_read_huge_page (struct node *node, vm_offset_t page,
   void **buf, int *writelock)
 {
-  error_t err;
+  error_t err = 0;
   int offs = 0;
   pthread_rwlock_t *lock = NULL;
   int left = vm_page_size;
diff --git a/trans/random.c b/trans/random.c
index b68354e..7e3d3eb 100644
--- a/trans/random.c
+++ b/trans/random.c
@@ -158,7 +158,7 @@ update_random_seed_file (void)
 static error_t
 read_random_seed_file (void)
 {
-  error_t err;
+  error_t err = 0;
   int fd;
   struct stat s;
   void *map;
-- 
2.39.2




[PATCH hurd 04/11] Fix printf format specifiers

2023-12-29 Thread Flavio Cruz
---
 pci-arbiter/options.c | 2 +-
 utils/ftpdir.c| 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/pci-arbiter/options.c b/pci-arbiter/options.c
index e0455f4..e578810 100644
--- a/pci-arbiter/options.c
+++ b/pci-arbiter/options.c
@@ -379,7 +379,7 @@ netfs_append_args (char **argz, size_t * argz_len)
 }
 
   if (fs->params.node_cache_max != NODE_CACHE_MAX)
-ADD_OPT ("--ncache=%u", fs->params.node_cache_max);
+ADD_OPT ("--ncache=%zu", fs->params.node_cache_max);
 
   if (fs->params.next_task != MACH_PORT_NULL)
 ADD_OPT ("--next-task=%u", fs->params.next_task);
diff --git a/utils/ftpdir.c b/utils/ftpdir.c
index 86ef58f..dd4d65d 100644
--- a/utils/ftpdir.c
+++ b/utils/ftpdir.c
@@ -203,7 +203,7 @@ pdirent (const char *name, const struct stat *st, const 
char *symlink_target,
 {
   char timebuf[20];
   strftime (timebuf, sizeof timebuf, "%Y-%m-%d %H:%M", localtime 
(>st_mtime));
-  printf ("%6o %2ld %5d %5d %6" PRIi64 "  %s  %s\n",
+  printf ("%6o %2zu %5d %5d %6" PRIi64 "  %s  %s\n",
  st->st_mode, st->st_nlink, st->st_uid, st->st_gid, st->st_size,
  timebuf, name);
   if (symlink_target)
-- 
2.39.2




[PATCH hurd 05/11] x86_64: utmp uses int32_t to store time so use a temporary variable

2023-12-29 Thread Flavio Cruz
---
 utils/login.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/utils/login.c b/utils/login.c
index 3134c4a..3ed5121 100644
--- a/utils/login.c
+++ b/utils/login.c
@@ -157,12 +157,17 @@ static void
 add_utmp_entry (char *args, unsigned args_len, int inherit_host)
 {
   struct utmp utmp;
+  struct timeval current_time;
   char const *host = 0;
   long addr = 0;
 
   memset (, 0, sizeof(utmp));
 
-  gettimeofday (_tv, 0);
+  gettimeofday (_time, 0);
+  /* For x86_64, sizeof(utmp.ut_tv) != sizeof(struct timeval) */
+  utmp.ut_tv.tv_sec = (int32_t) current_time.tv_sec;
+  utmp.ut_tv.tv_usec = (int32_t) current_time.tv_usec;
+
   strncpy (utmp.ut_name, envz_get (args, args_len, "USER") ?: "",
   sizeof (utmp.ut_name));
 
-- 
2.39.2




[PATCH hurd 07/11] Fix a few pointer related warnings.

2023-12-29 Thread Flavio Cruz
---
 utils/rpctrace.c   | 4 ++--
 utils/vmallocate.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/utils/rpctrace.c b/utils/rpctrace.c
index 589ce8f..f7046a0 100644
--- a/utils/rpctrace.c
+++ b/utils/rpctrace.c
@@ -810,10 +810,10 @@ print_contents (mach_msg_header_t *inp,
   int first = 1;
 
   /* Process the message data, wrapping ports and printing data.  */
-  while (msg_buf_ptr < (char *) inp + inp->msgh_size)
+  while ((char *) msg_buf_ptr < (char *) inp + inp->msgh_size)
 {
   mach_msg_type_t *const type = msg_buf_ptr;
-  mach_msg_type_long_t *const lt = (void *) type;
+  mach_msg_type_long_t *const lt = (mach_msg_type_long_t *) type;
   void *data;
   mach_msg_type_number_t nelt; /* Number of data items.  */
   mach_msg_type_size_t eltsize; /* Bytes per item.  */
diff --git a/utils/vmallocate.c b/utils/vmallocate.c
index 039b309..b7eafed 100644
--- a/utils/vmallocate.c
+++ b/utils/vmallocate.c
@@ -207,7 +207,7 @@ main (int argc, char **argv)
 *p = 1;
 
   if (verbose > 1
-  && ((unsigned int) (p - address) & ((1U<<20) - 1)) == 0)
+  && ((uintptr_t) (p - address) & ((1UL<<20) - 1)) == 0)
 fprintf (stderr, "\r%"PRIu64,
  allocated
  + ((uint64_t) (uintptr_t) p - (uint64_t) address));
-- 
2.39.2




[PATCH hurd 09/11] Fix overflow issues in tmpfs and vmallocate

2023-12-29 Thread Flavio Cruz
---
 tmpfs/tmpfs.c  | 2 +-
 utils/vmallocate.c | 7 +--
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/tmpfs/tmpfs.c b/tmpfs/tmpfs.c
index 02d4bd8..d28806a 100644
--- a/tmpfs/tmpfs.c
+++ b/tmpfs/tmpfs.c
@@ -39,7 +39,7 @@ char *diskfs_disk_name = "none";
 int diskfs_default_sync_interval = 0;
 
 /* We must supply some claimed limits, though we don't impose any new ones.  */
-int diskfs_link_max = (1ULL << (sizeof (nlink_t) * CHAR_BIT)) - 1;
+int diskfs_link_max = INT_MAX;
 int diskfs_name_max = 255; /* dirent d_namlen limit */
 int diskfs_maxsymlinks = 8;
 
diff --git a/utils/vmallocate.c b/utils/vmallocate.c
index b7eafed..fde8e76 100644
--- a/utils/vmallocate.c
+++ b/utils/vmallocate.c
@@ -160,8 +160,11 @@ main (int argc, char **argv)
   struct child *c, *children = NULL;
   process_t proc = getproc ();
 
-  /* We must make sure that chunk_size fits into vm_size_t.  */
-  assert_backtrace (chunk_size <= 1U << (sizeof (vm_size_t) * 8 - 1));
+  /* We must make sure that chunk_size fits into vm_size_t.
+   * We assume sizeof (vm_size_t) = sizeof (uintptr_t). */
+  _Static_assert (sizeof (vm_size_t) == sizeof (uintptr_t),
+  "expected sizeof (vm_size_t) == sizeof (uintptr_t).");
+  assert_backtrace (chunk_size <= UINTPTR_MAX);
 
   /* Parse our arguments.  */
   argp_parse (, argc, argv, 0, 0, 0);
-- 
2.39.2




[PATCH hurd 08/11] proxy-defpager: add missing return statement

2023-12-29 Thread Flavio Cruz
---
 trans/proxy-defpager.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/trans/proxy-defpager.c b/trans/proxy-defpager.c
index 386f1b6..314ce9f 100644
--- a/trans/proxy-defpager.c
+++ b/trans/proxy-defpager.c
@@ -124,6 +124,8 @@ S_default_pager_paging_storage_new (mach_port_t 
default_pager,
 return err;
 
   mach_port_deallocate (mach_task_self (), device);
+
+  return 0;
 }
 
 #ifndef __x86_64__
-- 
2.39.2




[PATCH hurd 10/11] libftpconn: add out >= 2 condition to make GCC happy

2023-12-29 Thread Flavio Cruz
---
 libftpconn/cmd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libftpconn/cmd.c b/libftpconn/cmd.c
index 9916d03..4b4c6fa 100644
--- a/libftpconn/cmd.c
+++ b/libftpconn/cmd.c
@@ -99,7 +99,7 @@ ftp_conn_cmd (struct ftp_conn *conn, const char *cmd, const 
char *arg,
snprintf (buf, sizeof buf, arg ? "%s %s\r\n" : "%s\r\n", cmd, arg);
   err = _write (conn->control, buf, out);
 
-  if (!err && conn->hooks && conn->hooks->cntl_debug)
+  if (!err && conn->hooks && conn->hooks->cntl_debug && out >= 2)
{
  buf[out - 2] = '\0';  /* Stomp the CR & NL.  */
  (* conn->hooks->cntl_debug) (conn, FTP_CONN_CNTL_DEBUG_CMD, buf);
-- 
2.39.2




[PATCH hurd 02/11] Cast bootinfo to struct diskfs_control * to silence warning

2023-12-29 Thread Flavio Cruz
---
 libdiskfs/boot-start.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libdiskfs/boot-start.c b/libdiskfs/boot-start.c
index e8c09bc..8c159f3 100644
--- a/libdiskfs/boot-start.c
+++ b/libdiskfs/boot-start.c
@@ -464,7 +464,7 @@ diskfs_S_fsys_getpriv (struct diskfs_control 
*init_bootstrap_port,
   error_t err;
 
   if (!init_bootstrap_port
-  || init_bootstrap_port != bootinfo)
+  || init_bootstrap_port != (struct diskfs_control *) bootinfo)
 return EOPNOTSUPP;
 
   err = get_privileged_ports (host_priv, dev_master);
-- 
2.39.2




[PATCH hurd 3/3] Mark msg_thread as noreturn

2023-12-29 Thread Flavio Cruz
---
 boot/boot.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/boot/boot.c b/boot/boot.c
index 0d7ae74..d773bd1 100644
--- a/boot/boot.c
+++ b/boot/boot.c
@@ -775,7 +775,7 @@ main (int argc, char **argv, char **envp)
 }
 }
 
-void *
+void * __attribute__ ((noreturn))
 msg_thread (void *arg)
 {
   while (1)
-- 
2.39.2




[PATCH hurd 2/3] Replace deprecated sigmask with sigset_t calls

2023-12-29 Thread Flavio Cruz
---
 exec/hashexec.c |  9 +++--
 libdiskfs/disk-pager.c  |  4 +++-
 libpager/pager-memcpy.c | 11 ---
 libstore/memobj.c   | 11 ---
 startup/startup.c   |  9 ++---
 5 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/exec/hashexec.c b/exec/hashexec.c
index 9e00704..a107291 100644
--- a/exec/hashexec.c
+++ b/exec/hashexec.c
@@ -53,6 +53,11 @@ check_hashbang (struct execdata *e,
   size_t new_argvlen;
   mach_port_t *new_dtable = NULL;
   mach_msg_type_number_t new_dtablesize;
+  sigset_t arg_env_sigset;
+
+  sigemptyset (_env_sigset);
+  sigaddset (_env_sigset, SIGSEGV);
+  sigaddset (_env_sigset, SIGBUS);
 
   file_t user_fd (int fd)
 {
@@ -293,7 +298,7 @@ check_hashbang (struct execdata *e,
  if (strchr (name, '/') != NULL)
error = lookup (name, 0, _file);
  else if ((error = hurd_catch_signal
-   (sigmask (SIGBUS) | sigmask (SIGSEGV),
+   (arg_env_sigset,
 (vm_address_t) envp, (vm_address_t) envp + envplen,
 _path, SIG_ERR)))
name_file = MACH_PORT_NULL;
@@ -416,7 +421,7 @@ check_hashbang (struct execdata *e,
}
 
   /* Set up the arguments.  */
-  hurd_catch_signal (sigmask (SIGSEGV) | sigmask (SIGBUS),
+  hurd_catch_signal (arg_env_sigset,
 (vm_address_t) argv, (vm_address_t) argv + argvlen,
 _args, _handler);
 }
diff --git a/libdiskfs/disk-pager.c b/libdiskfs/disk-pager.c
index 1a5d8bf..7af0e3b 100644
--- a/libdiskfs/disk-pager.c
+++ b/libdiskfs/disk-pager.c
@@ -29,7 +29,6 @@ struct pager_requests *diskfs_disk_pager_requests;
 static void fault_handler (int sig, long int sigcode, struct sigcontext *scp);
 static struct hurd_signal_preemptor preemptor =
   {
-  signals: sigmask (SIGSEGV) | sigmask (SIGBUS),
   preemptor: NULL,
   handler: (sighandler_t) _handler,
   };
@@ -73,6 +72,9 @@ diskfs_start_disk_pager (struct user_pager_info *upi,
   /* Set up the signal preemptor to catch faults on the disk image.  */
   preemptor.first = (vm_address_t) *image;
   preemptor.last = ((vm_address_t) *image + size);
+  sigemptyset ();
+  sigaddset (, SIGSEGV);
+  sigaddset (, SIGBUS);
   hurd_preempt_signals ();
 
   /* We have the mapping; we no longer need the send right.  */
diff --git a/libpager/pager-memcpy.c b/libpager/pager-memcpy.c
index caaf6f2..2ef42a7 100644
--- a/libpager/pager-memcpy.c
+++ b/libpager/pager-memcpy.c
@@ -208,9 +208,14 @@ pager_memcpy (struct pager *pager, memory_object_t memobj,
   window_size = 0;
 
   if (sigsetjmp (buf, 1) == 0)
-hurd_catch_signal (sigmask (SIGSEGV) | sigmask (SIGBUS),
-  window, window + window_size,
-  _copy, (sighandler_t) );
+{
+  sigset_t mask;
+  sigemptyset ();
+  sigaddset (, SIGSEGV);
+  sigaddset (, SIGBUS);
+  hurd_catch_signal (mask, window, window + window_size,
+_copy, (sighandler_t) );
+}
 
   if (! err)
 assert_backtrace (n == 0);
diff --git a/libstore/memobj.c b/libstore/memobj.c
index ea2d7b9..e98e1b2 100644
--- a/libstore/memobj.c
+++ b/libstore/memobj.c
@@ -113,9 +113,14 @@ memobj_memcpy (memory_object_t memobj,
 return 0;
 
   if (sigsetjmp (buf, 1) == 0)
-hurd_catch_signal (sigmask (SIGSEGV) | sigmask (SIGBUS),
-  window, window + windowsize,
-  , (sighandler_t) );
+{
+  sigset_t mask;
+  sigemptyset ();
+  sigaddset (, SIGSEGV);
+  sigaddset (, SIGBUS);
+  hurd_catch_signal (mask, window, window + windowsize,
+, (sighandler_t) );
+}
 
   if (window)
 munmap ((caddr_t) window, windowsize);
diff --git a/startup/startup.c b/startup/startup.c
index 862572c..27af818 100644
--- a/startup/startup.c
+++ b/startup/startup.c
@@ -826,9 +826,12 @@ main (int argc, char **argv, char **envp)
   /* All programs we start should ignore job control stop signals.
  That way Posix.1 B.2.2.2 is satisfied where it says that programs
  not run under job control shells are protected.  */
-  default_ints[INIT_SIGIGN] = (sigmask (SIGTSTP)
-  | sigmask (SIGTTIN)
-  | sigmask (SIGTTOU));
+  sigset_t sigmask;
+  sigemptyset ();
+  sigaddset (, SIGTSTP);
+  sigaddset (, SIGTTIN);
+  sigaddset (, SIGTTOU);
+  default_ints[INIT_SIGIGN] = sigmask;
 
   default_ports[INIT_PORT_BOOTSTRAP] = startup;
   run ("/hurd/proc", default_ports, , proc_insert_ports);
-- 
2.39.2




[PATCH hurd 1/3] pfinet and pci-arbiter: update server handlers to return kern_return_t to fix -Werror=enum-int-mismatch warnings

2023-12-29 Thread Flavio Cruz
---
 pci-arbiter/pci-ops.c | 10 +++
 pfinet/iioctl-ops.c   | 10 +++
 pfinet/io-ops.c   | 64 +--
 pfinet/main.c |  2 +-
 pfinet/pfinet-ops.c   |  4 +--
 pfinet/socket-ops.c   | 32 +++---
 pfinet/tunnel.c   | 24 
 7 files changed, 73 insertions(+), 73 deletions(-)

diff --git a/pci-arbiter/pci-ops.c b/pci-arbiter/pci-ops.c
index 2f9f529..bbe43f3 100644
--- a/pci-arbiter/pci-ops.c
+++ b/pci-arbiter/pci-ops.c
@@ -78,7 +78,7 @@ calculate_ndevs (struct iouser *user)
  *
  * `*datalen' is updated.
  */
-error_t
+kern_return_t
 S_pci_conf_read (struct protid * master, int reg, char **data,
 mach_msg_type_number_t * datalen, vm_size_t amount)
 {
@@ -127,7 +127,7 @@ S_pci_conf_read (struct protid * master, int reg, char 
**data,
 }
 
 /* Write `datalen' bytes from `data'. `amount' is updated. */
-error_t
+kern_return_t
 S_pci_conf_write (struct protid * master, int reg, const char *data, 
mach_msg_type_number_t datalen,
  vm_size_t * amount)
 {
@@ -165,7 +165,7 @@ S_pci_conf_write (struct protid * master, int reg, const 
char *data, mach_msg_ty
 }
 
 /* Write in `amount' the number of devices allowed for the user. */
-error_t
+kern_return_t
 S_pci_get_ndevs (struct protid * master, mach_msg_type_number_t * amount)
 {
   /* This RPC may only be addressed to the root node */
@@ -181,7 +181,7 @@ S_pci_get_ndevs (struct protid * master, 
mach_msg_type_number_t * amount)
  * Return in `data' the information about the available memory
  * regions in the given device.
  */
-error_t
+kern_return_t
 S_pci_get_dev_regions (struct protid * master, char **data, 
mach_msg_type_number_t * datalen)
 {
   error_t err;
@@ -232,7 +232,7 @@ S_pci_get_dev_regions (struct protid * master, char **data, 
mach_msg_type_number
 /*
  * Return in `data' the information about the expansion rom of the given device
  */
-error_t
+kern_return_t
 S_pci_get_dev_rom (struct protid * master, char **data, mach_msg_type_number_t 
* datalen)
 {
   error_t err;
diff --git a/pfinet/iioctl-ops.c b/pfinet/iioctl-ops.c
index 7673f3a..dc1abea 100644
--- a/pfinet/iioctl-ops.c
+++ b/pfinet/iioctl-ops.c
@@ -519,7 +519,7 @@ SIOCGIF (brdaddr, BRDADDR);
 SIOCGIF (netmask, NETMASK);
 
 /* 39 SIOCGIFHWADDR -- Get the hardware address of a network interface.  */
-error_t
+kern_return_t
 S_iioctl_siocgifhwaddr (struct sock_user *user,
ifname_t ifname,
sockaddr_t *addr)
@@ -544,7 +544,7 @@ S_iioctl_siocgifhwaddr (struct sock_user *user,
 }
 
 /* 51 SIOCGIFMTU -- Get mtu of a network interface.  */
-error_t
+kern_return_t
 S_iioctl_siocgifmtu (struct sock_user *user,
 ifname_t ifnam,
 int *mtu)
@@ -564,7 +564,7 @@ S_iioctl_siocgifmtu (struct sock_user *user,
 }
 
 /* 51 SIOCSIFMTU -- Set mtu of a network interface.  */
-error_t
+kern_return_t
 S_iioctl_siocsifmtu (struct sock_user *user,
 const ifname_t ifnam,
 int mtu)
@@ -598,7 +598,7 @@ S_iioctl_siocsifmtu (struct sock_user *user,
 }
 
 /* 100 SIOCGIFINDEX -- Get index number of a network interface.  */
-error_t
+kern_return_t
 S_iioctl_siocgifindex (struct sock_user *user,
   ifname_t ifnam,
   int *index)
@@ -618,7 +618,7 @@ S_iioctl_siocgifindex (struct sock_user *user,
 }
 
 /* 101 SIOCGIFNAME -- Get name of a network interface from index number.  */
-error_t
+kern_return_t
 S_iioctl_siocgifname (struct sock_user *user,
  ifname_t ifnam,
  int *index)
diff --git a/pfinet/io-ops.c b/pfinet/io-ops.c
index e1a6608..818f113 100644
--- a/pfinet/io-ops.c
+++ b/pfinet/io-ops.c
@@ -34,7 +34,7 @@
 #include 
 #include 
 
-error_t
+kern_return_t
 S_io_write (struct sock_user *user,
const_data_t data,
mach_msg_type_number_t datalen,
@@ -67,7 +67,7 @@ S_io_write (struct sock_user *user,
   return err;
 }
 
-error_t
+kern_return_t
 S_io_read (struct sock_user *user,
   data_t *data,
   mach_msg_type_number_t *datalen,
@@ -124,7 +124,7 @@ S_io_read (struct sock_user *user,
   return err;
 }
 
-error_t
+kern_return_t
 S_io_seek (struct sock_user *user,
   off_t offset,
   int whence,
@@ -133,7 +133,7 @@ S_io_seek (struct sock_user *user,
   return user ? ESPIPE : EOPNOTSUPP;
 }
 
-error_t
+kern_return_t
 S_io_readable (struct sock_user *user,
   vm_size_t *amount)
 {
@@ -183,7 +183,7 @@ S_io_readable (struct sock_user *user,
   return err;
 }
 
-error_t
+kern_return_t
 S_io_set_all_openmodes (struct sock_user *user,
int bits)
 {
@@ -199,7 +199,7 @@ S_io_set_all_openmodes (struct sock_user *user,
   return 0;
 }
 
-error_t
+kern_return_t
 S_io_get_openmodes (struct sock_user *user,
int *bits)
 {
@@ -223,7 +223,7 @@ S_io_get_openmodes (struct sock_user *user,
   return 0;
 }
 
-error_t

[PATCH mig] Use char* for inlined arrays of char in user headers

2023-12-29 Thread Flavio Cruz
This changes how we declare RPC user prototypes for device_read_inband
to use "char *data" rather than "io_buf_ptr_inband_t data". It is more
standard to pass a pointer to represent arrays compared to "char [128]". This
fixes a warning in console-client since GCC won't complain we are not
passing an exact char [128].

Also updated code to use const_io_buf_ptr_inband_t for
device_write_inband. This is a pointer to const data rather than a const
pointer.
---
 utils.c | 30 --
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/utils.c b/utils.c
index 0d69cb2..a6c895b 100644
--- a/utils.c
+++ b/utils.c
@@ -160,12 +160,19 @@ UserVarQualifier(const argument_t *arg)
 if (!UserVarConst(arg))
return "";
 
-if (arg->argType->itIndefinite ||
-   arg->argType->itInName == MACH_MSG_TYPE_STRING_C ||
-   !strcmp(arg->argType->itUserType, "string_t"))
+const ipc_type_t *it = arg->argType;
+
+if (it->itIndefinite ||
+   it->itInName == MACH_MSG_TYPE_STRING_C ||
+   (it->itVarArray && !strcmp(it->itElement->itUserType, "char")) ||
+   !strcmp(it->itUserType, "string_t"))
 /* This is a pointer, so we have to use the const_foo type to
   make const qualify the data, not the pointer.
 
+  Or this is a pointer to a variable array. For now we only support 
arrays of char
+  but we can remove that condition if we define const typedefs for all 
types that
+  require it.
+
   Or this is a string_t, which should use const_string_t to avoid
   forcing the caller to respect the definite string size */
return "const_";
@@ -176,10 +183,21 @@ UserVarQualifier(const argument_t *arg)
 void
 WriteUserVarDecl(FILE *file, const argument_t *arg)
 {
-const char *qualif = UserVarQualifier(arg);
-const char *ref = arg->argByReferenceUser ? "*" : "";
+const ipc_type_t *it = arg->argType;
 
-fprintf(file, "\t%s%s %s%s", qualif, arg->argType->itUserType, ref, 
arg->argVarName);
+if (it->itInLine && it->itVarArray && !it->itIndefinite &&
+   !UserVarConst(arg) &&
+   !strcmp(it->itElement->itUserType, "char"))
+{
+   /* For variable arrays like "array[*:128] of char" we prefer to use 
"char *param"
+* as the argument since it is more standard than using "char 
param[128]".
+*/
+   fprintf(file, "\tchar *%s /* max of %d elements */", arg->argVarName, 
it->itNumber);
+} else {
+   const char *qualif = UserVarQualifier(arg);
+   const char *ref = arg->argByReferenceUser ? "*" : "";
+   fprintf(file, "\t%s%s %s%s", qualif, it->itUserType, ref, 
arg->argVarName);
+}
 }
 
 /* Returns whether parameter should be qualified with const because we will 
only
-- 
2.39.2




[PATCH hurd] Update server handlers to return kern_return_error to fix -Werror=enum-int-mismatch warnings

2023-12-13 Thread Flavio Cruz
MiG expects those to return kern_return_t.
---
 acpi/acpi-ops.c|  4 ++--
 boot/boot.c|  2 +-
 console-client/trans.c | 10 
 console/display.c  |  8 +++
 ext2fs/storeinfo.c |  2 +-
 fatfs/inode.c  |  2 +-
 fatfs/main.c   |  2 +-
 isofs/inode.c  |  2 +-
 libdiskfs/dir-lookup.c |  2 +-
 libdiskfs/file-chmod.c |  2 +-
 libdiskfs/file-get-fs-opts.c   |  2 +-
 libdiskfs/file-getfh.c |  2 +-
 libdiskfs/file-record-lock.c   |  2 +-
 libdiskfs/file-reparent.c  |  2 +-
 libdiskfs/fsys-forward.c   |  2 +-
 libdiskfs/fsys-get-children.c  |  2 +-
 libdiskfs/fsys-get-source.c|  2 +-
 libdiskfs/fsys-getfile.c   |  2 +-
 libdiskfs/fsys-goaway.c|  2 +-
 libdiskfs/fsys-options.c   |  2 +-
 libdiskfs/io-identity.c|  2 +-
 libmachdev/trivfs_server.c |  2 +-
 libnetfs/dir-link.c|  2 +-
 libnetfs/dir-lookup.c  |  2 +-
 libnetfs/dir-mkdir.c   |  2 +-
 libnetfs/dir-mkfile.c  |  2 +-
 libnetfs/dir-notice-changes.c  |  2 +-
 libnetfs/dir-readdir.c |  2 +-
 libnetfs/dir-rename.c  |  2 +-
 libnetfs/dir-rmdir.c   |  2 +-
 libnetfs/dir-unlink.c  |  2 +-
 libnetfs/file-chauthor.c   |  2 +-
 libnetfs/file-check-access.c   |  2 +-
 libnetfs/file-chflags.c|  2 +-
 libnetfs/file-chmod.c  |  2 +-
 libnetfs/file-chown.c  |  2 +-
 libnetfs/file-get-fs-options.c |  2 +-
 libnetfs/file-get-storage-info.c   |  2 +-
 libnetfs/file-get-transcntl.c  |  2 +-
 libnetfs/file-get-translator.c |  2 +-
 libnetfs/file-getcontrol.c |  2 +-
 libnetfs/file-getlinknode.c|  2 +-
 libnetfs/file-lock-stat.c  |  2 +-
 libnetfs/file-lock.c   |  2 +-
 libnetfs/file-reparent.c   |  2 +-
 libnetfs/file-set-size.c   |  2 +-
 libnetfs/file-set-translator.c |  2 +-
 libnetfs/file-statfs.c |  2 +-
 libnetfs/file-sync.c   |  2 +-
 libnetfs/file-syncfs.c |  2 +-
 libnetfs/file-utimes.c |  4 ++--
 libnetfs/fsstubs.c |  6 ++---
 libnetfs/fsys-get-children.c   |  2 +-
 libnetfs/fsys-get-options.c|  2 +-
 libnetfs/fsys-get-source.c |  2 +-
 libnetfs/fsys-getroot.c|  2 +-
 libnetfs/fsys-goaway.c |  2 +-
 libnetfs/fsys-set-options.c|  2 +-
 libnetfs/fsys-syncfs.c |  2 +-
 libnetfs/fsysstubs.c   | 10 
 libnetfs/io-async.c|  2 +-
 libnetfs/io-clear-some-openmodes.c |  2 +-
 libnetfs/io-duplicate.c|  2 +-
 libnetfs/io-get-icky-async-id.c|  2 +-
 libnetfs/io-get-openmodes.c|  2 +-
 libnetfs/io-get-owner.c|  2 +-
 libnetfs/io-identity.c |  2 +-
 libnetfs/io-mod-owner.c|  2 +-
 libnetfs/io-pathconf.c |  2 +-
 libnetfs/io-read.c |  2 +-
 libnetfs/io-readable.c |  2 +-
 libnetfs/io-reauthenticate.c   |  2 +-
 libnetfs/io-restrict-auth.c|  2 +-
 libnetfs/io-seek.c |  2 +-
 libnetfs/io-select.c   |  4 ++--
 libnetfs/io-set-all-openmodes.c|  2 +-
 libnetfs/io-set-some-openmodes.c   |  2 +-
 libnetfs/io-stat.c |  2 +-
 libnetfs/io-write.c|  2 +-
 libnetfs/iostubs.c | 20 
 libports/notify-dead-name.c|  2 +-
 libports/notify-msg-accepted.c |  2 +-
 libports/notify-no-senders.c   |  2 +-
 libports/notify-port-deleted.c |  2 +-
 libports/notify-port-destroyed.c   |  2 +-
 libports/notify-send-once.c|  2 +-
 libtrivfs/file-access.c|  2 +-
 libtrivfs/file-get-fs-options.c|  2 +-
 libtrivfs/file-get-storage-info.c  |  2 +-
 libtrivfs/file-reparent.c  |  2 +-
 libtrivfs/fsys-forward.c   |  2 +-
 libtrivfs/fsys-get-children.c  |  2 +-
 libtrivfs/fsys-get-options.c   |  2 +-
 libtrivfs/fsys-get-source.c|  2 +-
 libtrivfs/fsys-set-options.c   |  2 +-
 libtrivfs/io-identity.c|  2 +-
 libtrivfs/io-modes-set.c   |  2 +-
 pflocal/fs.c   |  2 +-
 pflocal/io.c   | 32 -
 pflocal/pf.c   |  8 +++
 pflocal/socket.c   | 24 +--
 proc/mgt.c | 12 +-
 startup/startup.c  | 14 +--
 storeio/io.c   | 34 +-
 term/devio.c   |  2 +-
 term/ptyio.c   | 10 
 term/users.c   | 38 +++---
 tmpfs/node.c   |  2 +-
 trans/crash.c  |  

[PATCH glibc] Update code to handle the new ABI for sending inlined port rights.

2023-12-13 Thread Flavio Cruz
For i686, this change is no op but for x86_64 it forces all inlined port
rights to be 8 bytes long.
---
 hurd/intr-msg.c| 26 --
 mach/msg-destroy.c | 12 +---
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/hurd/intr-msg.c b/hurd/intr-msg.c
index 24184f827f..9912f4f1f3 100644
--- a/hurd/intr-msg.c
+++ b/hurd/intr-msg.c
@@ -199,6 +199,28 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
__vm_deallocate (__mach_task_self (), (vm_address_t) data, 
length);
}
 
+ inline void clean_inlined_ports (mach_port_name_inlined_t *ports)
+   {
+ mach_msg_type_number_t i;
+ switch (name)
+   {
+   case MACH_MSG_TYPE_MOVE_SEND:
+ for (i = 0; i < number; i++)
+   __mach_port_deallocate (__mach_task_self (), 
ports[i].name);
+ if (ty->msgtl_header.msgt_longform)
+   ty->msgtl_name = MACH_MSG_TYPE_COPY_SEND;
+ else
+   ty->msgtl_header.msgt_name = MACH_MSG_TYPE_COPY_SEND;
+ break;
+   case MACH_MSG_TYPE_COPY_SEND:
+   case MACH_MSG_TYPE_MOVE_RECEIVE:
+ break;
+   default:
+ if (MACH_MSG_TYPE_PORT_ANY (name))
+   assert (! "unexpected port type in interruptible RPC");
+   }
+   }
+
  char *data;
  if (ty->msgtl_header.msgt_longform)
{
@@ -215,11 +237,11 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
  data = (char *) ty + sizeof (mach_msg_type_t);
}
 
+ /* Calculate length of data in bytes.  */
  const vm_size_t length = ((number * size) + 7) >> 3;
  if (ty->msgtl_header.msgt_inline)
{
- /* Calculate length of data in bytes.  */
- clean_ports_and_memory (data, length, 0);
+ clean_inlined_ports ((mach_port_name_inlined_t *) data);
  /* Move to the next argument.  */
  ty = (void *) PTR_ALIGN_UP (data + length, __alignof__ 
(uintptr_t));
}
diff --git a/mach/msg-destroy.c b/mach/msg-destroy.c
index 19137baa62..8640c965bd 100644
--- a/mach/msg-destroy.c
+++ b/mach/msg-destroy.c
@@ -108,11 +108,17 @@ __mach_msg_destroy (mach_msg_header_t *msg)
addr = is_inline ? saddr : * (vm_offset_t *) saddr;
 
if (MACH_MSG_TYPE_PORT_ANY(name)) {
-   mach_port_t *ports = (mach_port_t *) addr;
mach_msg_type_number_t i;
 
-   for (i = 0; i < number; i++)
-   mach_msg_destroy_port(*ports++, name);
+   if (is_inline) {
+   mach_port_name_inlined_t *inlined_ports = 
(mach_port_name_inlined_t *)addr;
+   for (i = 0; i < number; i++)
+   mach_msg_destroy_port(inlined_ports[i].name, name);
+   } else {
+   mach_port_t *ports = (mach_port_t *) addr;
+   for (i = 0; i < number; i++)
+   mach_msg_destroy_port(ports[i], name);
+   }
}
 
if (is_inline) {
-- 
2.39.2




[PATCH gnumach] x86_64: Support 8 byte inlined port rights to avoid message resizing.

2023-12-13 Thread Flavio Cruz
If a port is inlined in a message, the user has to use
mach_port_name_inlined_t to define each port. Out of line memory
continues to use mach_port_name_t since that memory has to be copied to
the kernel anyway.

Both copyinmsg and copyoutmsg can be reduced to nothing (if we ignore
USER32) as a follow up but kept this patch simple for ease of review.
---
 i386/i386/copy_user.h  | 12 
 include/mach/message.h | 18 
 x86_64/copy_user.c | 67 +-
 3 files changed, 83 insertions(+), 14 deletions(-)

diff --git a/i386/i386/copy_user.h b/i386/i386/copy_user.h
index 5cdbfa80..3d1c7278 100644
--- a/i386/i386/copy_user.h
+++ b/i386/i386/copy_user.h
@@ -87,16 +87,14 @@ static inline int copyout_port(const mach_port_t *kaddr, 
mach_port_name_t *uaddr
 #endif /* __x86_64__ */
 }
 
-// XXX we could add another field to kmsg to store the user-side size, but 
then we
-// should check if we can  obtain it for rpc and notifications originating from
-// the kernel
-#ifndef __x86_64__
+#if defined(__x86_64__) && defined(USER32)
+/* For 32 bit userland, kernel and user land messages are not the same size. */
+size_t msg_usize(const mach_msg_header_t *kmsg);
+#else
 static inline size_t msg_usize(const mach_msg_header_t *kmsg)
 {
   return kmsg->msgh_size;
 }
-#else /* __x86_64__ */
-size_t msg_usize(const mach_msg_header_t *kmsg);
-#endif /* __x86_64__ */
+#endif /* __x86_64__ && USER32 */
 
 #endif /* COPY_USER_H */
diff --git a/include/mach/message.h b/include/mach/message.h
index 17d3592f..21e99896 100644
--- a/include/mach/message.h
+++ b/include/mach/message.h
@@ -221,6 +221,24 @@ typedef unsigned int mach_msg_type_name_t;
 typedef unsigned int mach_msg_type_size_t;
 typedef natural_t  mach_msg_type_number_t;
 
+/**
+ * Structure used for inlined port rights in messages.
+ *
+ * We use this to avoid having to perform message resizing in the kernel
+ * since userspace port rights might be smaller than kernel ports in 64 bit
+ * architectures.
+ */
+typedef struct {
+union {
+mach_port_name_t name;
+#ifdef KERNEL
+mach_port_t kernel_port;
+#else
+uintptr_t kernel_port_do_not_use;
+#endif  /* KERNEL */
+};
+} mach_port_name_inlined_t;
+
 typedef struct  {
 #ifdef __x86_64__
 /*
diff --git a/x86_64/copy_user.c b/x86_64/copy_user.c
index 0d3f301b..c6e125d9 100644
--- a/x86_64/copy_user.c
+++ b/x86_64/copy_user.c
@@ -265,8 +265,15 @@ static inline int copyout_unpack_msg_type(vm_offset_t 
kaddr,
   mach_msg_type_size_t orig_size = kmtl->msgtl_size;
   int ret;
 
-  if (MACH_MSG_TYPE_PORT_ANY(kmtl->msgtl_name))
+  if (MACH_MSG_TYPE_PORT_ANY(kmtl->msgtl_name)) {
+#ifdef USER32
 kmtl->msgtl_size = bytes_to_descsize(sizeof(mach_port_name_t));
+#else
+/* 64 bit ABI uses mach_port_name_inlined_t for inlined ports. */
+if (!kmt->msgt_inline)
+  kmtl->msgtl_size = bytes_to_descsize(sizeof(mach_port_name_t));
+#endif
+  }
   ret = copyout_mach_msg_type_long(kmtl, (void*)uaddr);
   kmtl->msgtl_size = orig_size;
   if (ret)
@@ -283,8 +290,15 @@ static inline int copyout_unpack_msg_type(vm_offset_t 
kaddr,
   mach_msg_type_size_t orig_size = kmt->msgt_size;
   int ret;
 
-  if (MACH_MSG_TYPE_PORT_ANY(kmt->msgt_name))
+  if (MACH_MSG_TYPE_PORT_ANY(kmt->msgt_name)) {
+#ifdef USER32
 kmt->msgt_size = bytes_to_descsize(sizeof(mach_port_name_t));
+#else
+/* 64 bit ABI uses mach_port_name_inlined_t for inlined ports. */
+if (!kmt->msgt_inline)
+  kmt->msgt_size = bytes_to_descsize(sizeof(mach_port_name_t));
+#endif
+  }
   ret = copyout_mach_msg_type(kmt, (void *)uaddr);
   kmt->msgt_size = orig_size;
   if (ret)
@@ -299,8 +313,10 @@ static inline int copyout_unpack_msg_type(vm_offset_t 
kaddr,
   return 0;
 }
 
+#ifdef USER32
 /*
- * Compute the user-space size of a message still in the kernel.
+ * Compute the user-space size of a message still in the kernel when processing
+ * messages from 32bit userland.
  * The message may be originating from userspace (in which case we could
  * optimize this by keeping the usize around) or from kernel space (we could
  * optimize if the message structure is fixed and known in advance).
@@ -333,7 +349,8 @@ size_t msg_usize(const mach_msg_header_t *kmsg)
 {
   if (MACH_MSG_TYPE_PORT_ANY(name))
 {
-  saddr += sizeof(mach_port_t) * number;
+  const vm_size_t length = sizeof(mach_port_t) * number;
+  saddr += length;
   usize += sizeof(mach_port_name_t) * number;
 }
   else
@@ -355,6 +372,7 @@ size_t msg_usize(const mach_msg_header_t *kmsg)
 }
   return usize;
 }
+#endif /* USER32 */
 
 /*
  * Expand the msg header and, if required, the msg body (ports, pointers)
@@ -423,6 +441,9 @@ int copyinmsg (const void *userbuf, void *kernelbuf, const 
size_t usize, 

[PATCH hurd] Update hurd code to handle the new ABI for sending inlined port rights.

2023-12-13 Thread Flavio Cruz
---
 libfshelp/start-translator-long.c | 16 
 proc/stubs.c  |  8 +---
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/libfshelp/start-translator-long.c 
b/libfshelp/start-translator-long.c
index 0b16e7d0..f788f0a7 100644
--- a/libfshelp/start-translator-long.c
+++ b/libfshelp/start-translator-long.c
@@ -39,7 +39,7 @@ struct fsys_startup_request
   mach_msg_type_t flagsType;
   int flags;
   mach_msg_type_t control_portType;
-  mach_port_t control_port;
+  mach_port_name_inlined_t control_port;
 };
 
 struct fsys_startup_reply
@@ -48,7 +48,7 @@ struct fsys_startup_reply
   mach_msg_type_t RetCodeType;
   kern_return_t RetCode;
   mach_msg_type_t realnodeType;
-  mach_port_t realnode;
+  mach_port_name_inlined_t realnode;
 };
 
 /* Wait around for an fsys_startup message on the port PORT from the
@@ -76,7 +76,7 @@ service_fsys_startup (fshelp_open_fn_t underlying_open_fn, 
void *cookie,
   const mach_msg_type_t control_portCheck =
 {
   .msgt_name = MACH_MSG_TYPE_PORT_SEND,
-  .msgt_size = 32,
+  .msgt_size = 8 * sizeof(mach_port_name_inlined_t),
   .msgt_number = 1,
   .msgt_inline = TRUE,
   .msgt_longform = FALSE,
@@ -96,7 +96,7 @@ service_fsys_startup (fshelp_open_fn_t underlying_open_fn, 
void *cookie,
   const mach_msg_type_t realnodeType =
 {
   .msgt_name = (unsigned char) MACH_MSG_TYPE_POLYMORPHIC,
-  .msgt_size = 32,
+  .msgt_size = 8 * sizeof(mach_port_name_inlined_t),
   .msgt_number = 1,
   .msgt_inline = TRUE,
   .msgt_longform = FALSE,
@@ -157,17 +157,17 @@ service_fsys_startup (fshelp_open_fn_t 
underlying_open_fn, void *cookie,
 {
   mach_msg_type_name_t realnode_type;
 
-  *control = request.startup.control_port;
+  *control = request.startup.control_port.name;
 
   reply.RetCode =
(*underlying_open_fn) (request.startup.flags,
-  , _type, task,
+  , _type, task,
   cookie);
 
   reply.realnodeType = realnodeType;
   reply.realnodeType.msgt_name = realnode_type;
 
-  if (!reply.RetCode && reply.realnode != MACH_PORT_NULL)
+  if (!reply.RetCode && reply.realnode.name != MACH_PORT_NULL)
/* The message can't be simple because of the port.  */
reply.head.msgh_bits |= MACH_MSGH_BITS_COMPLEX;
 }
@@ -180,7 +180,7 @@ service_fsys_startup (fshelp_open_fn_t underlying_open_fn, 
void *cookie,
   && reply.realnodeType.msgt_name == MACH_MSG_TYPE_MOVE_SEND)
 /* For MACH_SEND_INTERRUPTED, we'll have pseudo-received the message
and might have to clean up a generated send right.  */
-mach_port_deallocate (mach_task_self (), reply.realnode);
+mach_port_deallocate (mach_task_self (), reply.realnode.name);
 
   if (reply.RetCode)
 /* Make our error return be the earlier one.  */
diff --git a/proc/stubs.c b/proc/stubs.c
index dc621ba1..0b4a2cea 100644
--- a/proc/stubs.c
+++ b/proc/stubs.c
@@ -37,7 +37,7 @@ struct msg_sig_post_request
   mach_msg_type_t sigcode_type;
   natural_t sigcode;
   mach_msg_type_t refporttype;
-  mach_port_t refport;
+  mach_port_name_inlined_t refport;
 };
 
 /* Send the Mach message indicated by msg_spec.  */
@@ -124,14 +124,16 @@ send_signal (mach_port_t msgport,
 .refporttype = {
   /* Type descriptor for refport */
   .msgt_name = MACH_MSG_TYPE_COPY_SEND,
-  .msgt_size = 32,
+  .msgt_size = 8 * sizeof(mach_port_name_inlined_t),
   .msgt_number = 1,
   .msgt_inline = TRUE,
   .msgt_longform = FALSE,
   .msgt_deallocate = FALSE,
   .msgt_unused = 0
 },
-.refport = refport
+.refport = {
+  .name = refport
+}
   };
 
   err = mach_msg ((mach_msg_header_t *),
-- 
2.39.2




[PATCH mig] x86_64: adapt MiG generated stubs to use mach_port_name_inlined_t for inlined port rights.

2023-12-13 Thread Flavio Cruz
For i686, we just change the code to use mach_port_name_inlined_t when
defining the types. This is a no-op.

For x86_64, there's a few things that are different:
- In the server code, the server handler can get inlined ports and the
  array will be resized and cast as an array of mach_port_name_t. Output
  parameters have a similar treatment where the inlined array in the
  output is used as an array of mach_port_name_t but resized to look like
  a mach_port_name_inlined_t.
- In the user side, we follow the same approach. Input ports as arrays
  of mach_port_name_t are expanded into an array of mach_port_name_inlined_t.
  Output ports are then converted back into an array of
  mach_port_name_inlined_t so that they fit into the expected message
  format.

Essentially, regardless of whether port rights are inline or out of
line, user interfaces and server stubs always receive an array of port
rights, not mach_port_name_inlined_t. However, inlined port rights will
be exchanged using mach_port_name_inlined_t.
---
 cpu.sym   |   1 +
 global.c  |   4 +-
 parser.y  |   4 --
 routine.c |   6 ++
 server.c  | 167 +-
 type.c|  36 
 type.h|   5 ++
 user.c| 123 ++--
 utils.c   |  28 +++--
 9 files changed, 279 insertions(+), 95 deletions(-)

diff --git a/cpu.sym b/cpu.sym
index bee12f0..1ac2fae 100644
--- a/cpu.sym
+++ b/cpu.sym
@@ -105,6 +105,7 @@ expr sizeof(float)  sizeof_float
 expr sizeof(double)sizeof_double
 expr sizeof(uintptr_t) sizeof_uintptr_t
 expr sizeof(intptr_t)  sizeof_intptr_t
+expr (sizeof(uintptr_t)*8) sizeof_uintptr_t_in_bits
 expr sizeof(mach_msg_header_t) sizeof_mach_msg_header_t
 expr sizeof(mach_msg_type_long_t)  sizeof_mach_msg_type_long_t
 expr sizeof(mach_msg_type_t)   sizeof_mach_msg_type_t
diff --git a/global.c b/global.c
index 0ef1dca..bac667c 100644
--- a/global.c
+++ b/global.c
@@ -65,8 +65,8 @@ string_t InternalHeaderFileName = strNULL;
 string_t UserFileName = strNULL;
 string_t ServerFileName = strNULL;
 
-size_t port_size = port_name_size;
-size_t port_size_in_bits = port_name_size_in_bits;
+size_t port_size = sizeof_uintptr_t;
+size_t port_size_in_bits = sizeof_uintptr_t_in_bits;
 size_t complex_alignof = desired_complex_alignof;
 
 void
diff --git a/parser.y b/parser.y
index cac3379..5a73af8 100644
--- a/parser.y
+++ b/parser.y
@@ -210,10 +210,6 @@ Subsystem  :   SubsystemStart SubsystemMods
   IsKernelUser ? ", KernelUser" : "",
   IsKernelServer ? ", KernelServer" : "");
 }
-if (IsKernelUser || IsKernelServer) {
-port_size = vm_offset_size;
-port_size_in_bits = vm_offset_size_in_bits;
-}
 init_type();
 }
;
diff --git a/routine.c b/routine.c
index 3ae9298..8909f4d 100644
--- a/routine.c
+++ b/routine.c
@@ -517,6 +517,12 @@ rtAugmentArgKind(argument_t *arg)
 {
arg->argKind = akAddFeature(arg->argKind, akbPointer);
 }
+if (akCheck(arg->argKind, akbSendRcv) &&
+IS_64BIT_ABI &&
+it->itUserlandPort &&
+   akCheck(arg->argKind, akbIndefinite)) {
+   arg->argKind = akAddFeature(arg->argKind, akbPointer);
+}
 }
 
 /* arg->argType may be NULL in this function */
diff --git a/server.c b/server.c
index 00ca3f2..973e1f7 100644
--- a/server.c
+++ b/server.c
@@ -455,10 +455,27 @@ WriteTypeCheck(FILE *file, const argument_t *arg)
arg->argRequestPos, arg->argTTName,
arg->argLongForm ? "l" : "",
it->itNumber);
-   fprintf(file, "\t(In%dP->%s.msgt%s_size != %d)))\n",
-   arg->argRequestPos, arg->argTTName,
-   arg->argLongForm ? "l" : "",
-   it->itSize);
+   if (IS_64BIT_ABI && it->itUserlandPort && arg->argLongForm) {
+   /* 64 bit inlined ports are 8 bytes long but we use 
mach_port_name_t when passing them out of line. */
+   fprintf(file, "\t(In%dP->%s.msgtl_size != %d && 
In%dP->%s.msgtl_header.msgt_inline == TRUE) || \n",
+   arg->argRequestPos,
+   arg->argTTName,
+   it->itSize,
+   arg->argRequestPos,
+   arg->argTTName);
+   fprintf(file, "\t(In%dP->%s.msgtl_size != %d && 
In%dP->%s.msgtl_header.msgt_inline == FALSE)",
+   arg->argRequestPos,
+   arg->argTTName,
+   port_name_size_in_bits,
+   arg->argRequestPos,
+   arg->argTTName);
+   } else {
+   fprintf(file, "\t(In%dP->%s.msgt%s_size != %d)",
+   arg->argRequestPos, arg->argTTName,
+   arg->argLongForm ? "l" : "",
+   it->itSize);
+   }
+   fprintf(file, "))\n");
 }
 WriteMsgError(file, "MIG_BAD_ARGUMENTS");
 

Patch series to avoid message resizing for x86_64 (v2)

2023-12-13 Thread Flavio Cruz
Hello

Sending the updated patch series with the warnings fixed. The only
difference is in the glibc patch (added a cast when calling
clean_inlined_ports) and the MiG patch, which required a 3 line change
to add appropriate casts from mach_port_name_inlined_t* to mach_port_t*
in server.c.

Flavio





[PATCH gnumach] x86_64: Support 8 byte inlined port rights to avoid message resizing.

2023-11-29 Thread Flavio Cruz
If a port is inlined in a message, the user has to use
mach_port_name_inlined_t to define each port. Out of line memory
continues to use mach_port_name_t since that memory has to be copied to
the kernel anyway.

Both copyinmsg and copyoutmsg can be reduced to nothing (if we ignore
USER32) as a follow up but kept this patch simple for ease of review.
---
Now returning errors instead of failing assertions.

 i386/i386/copy_user.h  | 12 
 include/mach/message.h | 18 
 x86_64/copy_user.c | 67 +-
 3 files changed, 83 insertions(+), 14 deletions(-)

diff --git a/i386/i386/copy_user.h b/i386/i386/copy_user.h
index 5cdbfa80..3d1c7278 100644
--- a/i386/i386/copy_user.h
+++ b/i386/i386/copy_user.h
@@ -87,16 +87,14 @@ static inline int copyout_port(const mach_port_t *kaddr, 
mach_port_name_t *uaddr
 #endif /* __x86_64__ */
 }
 
-// XXX we could add another field to kmsg to store the user-side size, but 
then we
-// should check if we can  obtain it for rpc and notifications originating from
-// the kernel
-#ifndef __x86_64__
+#if defined(__x86_64__) && defined(USER32)
+/* For 32 bit userland, kernel and user land messages are not the same size. */
+size_t msg_usize(const mach_msg_header_t *kmsg);
+#else
 static inline size_t msg_usize(const mach_msg_header_t *kmsg)
 {
   return kmsg->msgh_size;
 }
-#else /* __x86_64__ */
-size_t msg_usize(const mach_msg_header_t *kmsg);
-#endif /* __x86_64__ */
+#endif /* __x86_64__ && USER32 */
 
 #endif /* COPY_USER_H */
diff --git a/include/mach/message.h b/include/mach/message.h
index 17d3592f..21e99896 100644
--- a/include/mach/message.h
+++ b/include/mach/message.h
@@ -221,6 +221,24 @@ typedef unsigned int mach_msg_type_name_t;
 typedef unsigned int mach_msg_type_size_t;
 typedef natural_t  mach_msg_type_number_t;
 
+/**
+ * Structure used for inlined port rights in messages.
+ *
+ * We use this to avoid having to perform message resizing in the kernel
+ * since userspace port rights might be smaller than kernel ports in 64 bit
+ * architectures.
+ */
+typedef struct {
+union {
+mach_port_name_t name;
+#ifdef KERNEL
+mach_port_t kernel_port;
+#else
+uintptr_t kernel_port_do_not_use;
+#endif  /* KERNEL */
+};
+} mach_port_name_inlined_t;
+
 typedef struct  {
 #ifdef __x86_64__
 /*
diff --git a/x86_64/copy_user.c b/x86_64/copy_user.c
index 0d3f301b..c6e125d9 100644
--- a/x86_64/copy_user.c
+++ b/x86_64/copy_user.c
@@ -265,8 +265,15 @@ static inline int copyout_unpack_msg_type(vm_offset_t 
kaddr,
   mach_msg_type_size_t orig_size = kmtl->msgtl_size;
   int ret;
 
-  if (MACH_MSG_TYPE_PORT_ANY(kmtl->msgtl_name))
+  if (MACH_MSG_TYPE_PORT_ANY(kmtl->msgtl_name)) {
+#ifdef USER32
 kmtl->msgtl_size = bytes_to_descsize(sizeof(mach_port_name_t));
+#else
+/* 64 bit ABI uses mach_port_name_inlined_t for inlined ports. */
+if (!kmt->msgt_inline)
+  kmtl->msgtl_size = bytes_to_descsize(sizeof(mach_port_name_t));
+#endif
+  }
   ret = copyout_mach_msg_type_long(kmtl, (void*)uaddr);
   kmtl->msgtl_size = orig_size;
   if (ret)
@@ -283,8 +290,15 @@ static inline int copyout_unpack_msg_type(vm_offset_t 
kaddr,
   mach_msg_type_size_t orig_size = kmt->msgt_size;
   int ret;
 
-  if (MACH_MSG_TYPE_PORT_ANY(kmt->msgt_name))
+  if (MACH_MSG_TYPE_PORT_ANY(kmt->msgt_name)) {
+#ifdef USER32
 kmt->msgt_size = bytes_to_descsize(sizeof(mach_port_name_t));
+#else
+/* 64 bit ABI uses mach_port_name_inlined_t for inlined ports. */
+if (!kmt->msgt_inline)
+  kmt->msgt_size = bytes_to_descsize(sizeof(mach_port_name_t));
+#endif
+  }
   ret = copyout_mach_msg_type(kmt, (void *)uaddr);
   kmt->msgt_size = orig_size;
   if (ret)
@@ -299,8 +313,10 @@ static inline int copyout_unpack_msg_type(vm_offset_t 
kaddr,
   return 0;
 }
 
+#ifdef USER32
 /*
- * Compute the user-space size of a message still in the kernel.
+ * Compute the user-space size of a message still in the kernel when processing
+ * messages from 32bit userland.
  * The message may be originating from userspace (in which case we could
  * optimize this by keeping the usize around) or from kernel space (we could
  * optimize if the message structure is fixed and known in advance).
@@ -333,7 +349,8 @@ size_t msg_usize(const mach_msg_header_t *kmsg)
 {
   if (MACH_MSG_TYPE_PORT_ANY(name))
 {
-  saddr += sizeof(mach_port_t) * number;
+  const vm_size_t length = sizeof(mach_port_t) * number;
+  saddr += length;
   usize += sizeof(mach_port_name_t) * number;
 }
   else
@@ -355,6 +372,7 @@ size_t msg_usize(const mach_msg_header_t *kmsg)
 }
   return usize;
 }
+#endif /* USER32 */
 
 /*
  * Expand the msg header and, if required, the msg body (ports, pointers)
@@ -423,6 +441,9 @@ int copyinmsg (const 

[PATCH gnumach] Use MACH_PORT_NAME_NULL and MACH_PORT_NAME_DEAD when checking for null or dead rights

2023-11-28 Thread Flavio Cruz
Comparing mach_port_name_t that is MACH_PORT_NAME_DEAD against
MACH_PORT_DEAD will always return false.
---
 ipc/ipc_space.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ipc/ipc_space.h b/ipc/ipc_space.h
index 9b199de..3f0eaa0 100644
--- a/ipc/ipc_space.h
+++ b/ipc/ipc_space.h
@@ -161,7 +161,7 @@ extern volatile boolean_t mach_port_deallocate_debug;
 static inline void
 ipc_entry_lookup_failed(mach_msg_header_t *msg, mach_port_name_t name)
 {
-   if (name == MACH_PORT_NULL || name == MACH_PORT_DEAD)
+   if (name == MACH_PORT_NAME_NULL || name == MACH_PORT_NAME_DEAD)
return;
printf("task %.*s looked up a bogus port %lu for %d, most probably a 
bug.\n", (int) sizeof current_task()->name, current_task()->name, (unsigned 
long) name, msg->msgh_id);
if (mach_port_deallocate_debug)
-- 
2.39.2




[PATCH gnumach] Reorder mach_msg_type_t fields to ensure msgt_name and msgt_size are byte aligned

2023-11-24 Thread Flavio Cruz
msgt_unused appears right after msgt_size since msgt_size can be reduced
to only 8 bits in the future, so we leave the door opened to make
msgt_unused 13 bits long.
---
 include/mach/message.h | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/include/mach/message.h b/include/mach/message.h
index 17d3592..906ae79 100644
--- a/include/mach/message.h
+++ b/include/mach/message.h
@@ -238,12 +238,12 @@ typedef struct  {
  * kernel. Otherwise, we would have to replicate some of the MiG logic
  * internally in the kernel.
  */
-unsigned int   msgt_inline : 1,
-   msgt_longform : 1,
-   msgt_deallocate : 1,
-   msgt_name : 8,
+unsigned int   msgt_name : 8,
msgt_size : 16,
-   msgt_unused : 5;
+   msgt_unused : 5,
+   msgt_inline : 1,
+   msgt_longform : 1,
+   msgt_deallocate : 1;
 mach_msg_type_number_t   msgt_number;
 #else
 unsigned int   msgt_name : 8,
@@ -263,12 +263,12 @@ typedef struct {
  * union to overlay with the old field names.  */
 mach_msg_type_tmsgtl_header;
 struct {
-unsigned int   msgtl_inline : 1,
-msgtl_longform : 1,
-msgtl_deallocate : 1,
-msgtl_name : 8,
+unsigned int   msgtl_name : 8,
 msgtl_size : 16,
-msgtl_unused : 5;
+msgtl_unused : 5,
+msgtl_inline : 1,
+msgtl_longform : 1,
+msgtl_deallocate : 1;
 mach_msg_type_number_t   msgtl_number;
 };
 };
-- 
2.39.2




[PATCH hurd] Update hurd code to handle the new ABI for sending inlined port rights.

2023-11-24 Thread Flavio Cruz
---
 libfshelp/start-translator-long.c | 16 
 proc/stubs.c  |  8 +---
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/libfshelp/start-translator-long.c 
b/libfshelp/start-translator-long.c
index 0b16e7d0..f788f0a7 100644
--- a/libfshelp/start-translator-long.c
+++ b/libfshelp/start-translator-long.c
@@ -39,7 +39,7 @@ struct fsys_startup_request
   mach_msg_type_t flagsType;
   int flags;
   mach_msg_type_t control_portType;
-  mach_port_t control_port;
+  mach_port_name_inlined_t control_port;
 };
 
 struct fsys_startup_reply
@@ -48,7 +48,7 @@ struct fsys_startup_reply
   mach_msg_type_t RetCodeType;
   kern_return_t RetCode;
   mach_msg_type_t realnodeType;
-  mach_port_t realnode;
+  mach_port_name_inlined_t realnode;
 };
 
 /* Wait around for an fsys_startup message on the port PORT from the
@@ -76,7 +76,7 @@ service_fsys_startup (fshelp_open_fn_t underlying_open_fn, 
void *cookie,
   const mach_msg_type_t control_portCheck =
 {
   .msgt_name = MACH_MSG_TYPE_PORT_SEND,
-  .msgt_size = 32,
+  .msgt_size = 8 * sizeof(mach_port_name_inlined_t),
   .msgt_number = 1,
   .msgt_inline = TRUE,
   .msgt_longform = FALSE,
@@ -96,7 +96,7 @@ service_fsys_startup (fshelp_open_fn_t underlying_open_fn, 
void *cookie,
   const mach_msg_type_t realnodeType =
 {
   .msgt_name = (unsigned char) MACH_MSG_TYPE_POLYMORPHIC,
-  .msgt_size = 32,
+  .msgt_size = 8 * sizeof(mach_port_name_inlined_t),
   .msgt_number = 1,
   .msgt_inline = TRUE,
   .msgt_longform = FALSE,
@@ -157,17 +157,17 @@ service_fsys_startup (fshelp_open_fn_t 
underlying_open_fn, void *cookie,
 {
   mach_msg_type_name_t realnode_type;
 
-  *control = request.startup.control_port;
+  *control = request.startup.control_port.name;
 
   reply.RetCode =
(*underlying_open_fn) (request.startup.flags,
-  , _type, task,
+  , _type, task,
   cookie);
 
   reply.realnodeType = realnodeType;
   reply.realnodeType.msgt_name = realnode_type;
 
-  if (!reply.RetCode && reply.realnode != MACH_PORT_NULL)
+  if (!reply.RetCode && reply.realnode.name != MACH_PORT_NULL)
/* The message can't be simple because of the port.  */
reply.head.msgh_bits |= MACH_MSGH_BITS_COMPLEX;
 }
@@ -180,7 +180,7 @@ service_fsys_startup (fshelp_open_fn_t underlying_open_fn, 
void *cookie,
   && reply.realnodeType.msgt_name == MACH_MSG_TYPE_MOVE_SEND)
 /* For MACH_SEND_INTERRUPTED, we'll have pseudo-received the message
and might have to clean up a generated send right.  */
-mach_port_deallocate (mach_task_self (), reply.realnode);
+mach_port_deallocate (mach_task_self (), reply.realnode.name);
 
   if (reply.RetCode)
 /* Make our error return be the earlier one.  */
diff --git a/proc/stubs.c b/proc/stubs.c
index dc621ba1..0b4a2cea 100644
--- a/proc/stubs.c
+++ b/proc/stubs.c
@@ -37,7 +37,7 @@ struct msg_sig_post_request
   mach_msg_type_t sigcode_type;
   natural_t sigcode;
   mach_msg_type_t refporttype;
-  mach_port_t refport;
+  mach_port_name_inlined_t refport;
 };
 
 /* Send the Mach message indicated by msg_spec.  */
@@ -124,14 +124,16 @@ send_signal (mach_port_t msgport,
 .refporttype = {
   /* Type descriptor for refport */
   .msgt_name = MACH_MSG_TYPE_COPY_SEND,
-  .msgt_size = 32,
+  .msgt_size = 8 * sizeof(mach_port_name_inlined_t),
   .msgt_number = 1,
   .msgt_inline = TRUE,
   .msgt_longform = FALSE,
   .msgt_deallocate = FALSE,
   .msgt_unused = 0
 },
-.refport = refport
+.refport = {
+  .name = refport
+}
   };
 
   err = mach_msg ((mach_msg_header_t *),
-- 
2.39.2




[PATCH glibc] Update code to handle the new ABI for sending inlined port rights.

2023-11-24 Thread Flavio Cruz
For i686, this change is no op but for x86_64 it forces all inlined port
rights to be 8 bytes long.
---
 hurd/intr-msg.c| 26 --
 mach/msg-destroy.c | 12 +---
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/hurd/intr-msg.c b/hurd/intr-msg.c
index 24184f827f..d52e90449e 100644
--- a/hurd/intr-msg.c
+++ b/hurd/intr-msg.c
@@ -199,6 +199,28 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
__vm_deallocate (__mach_task_self (), (vm_address_t) data, 
length);
}
 
+ inline void clean_inlined_ports (mach_port_name_inlined_t *ports)
+   {
+ mach_msg_type_number_t i;
+ switch (name)
+   {
+   case MACH_MSG_TYPE_MOVE_SEND:
+ for (i = 0; i < number; i++)
+   __mach_port_deallocate (__mach_task_self (), 
ports[i].name);
+ if (ty->msgtl_header.msgt_longform)
+   ty->msgtl_name = MACH_MSG_TYPE_COPY_SEND;
+ else
+   ty->msgtl_header.msgt_name = MACH_MSG_TYPE_COPY_SEND;
+ break;
+   case MACH_MSG_TYPE_COPY_SEND:
+   case MACH_MSG_TYPE_MOVE_RECEIVE:
+ break;
+   default:
+ if (MACH_MSG_TYPE_PORT_ANY (name))
+   assert (! "unexpected port type in interruptible RPC");
+   }
+   }
+
  char *data;
  if (ty->msgtl_header.msgt_longform)
{
@@ -215,11 +237,11 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
  data = (char *) ty + sizeof (mach_msg_type_t);
}
 
+ /* Calculate length of data in bytes.  */
  const vm_size_t length = ((number * size) + 7) >> 3;
  if (ty->msgtl_header.msgt_inline)
{
- /* Calculate length of data in bytes.  */
- clean_ports_and_memory (data, length, 0);
+ clean_inlined_ports (data);
  /* Move to the next argument.  */
  ty = (void *) PTR_ALIGN_UP (data + length, __alignof__ 
(uintptr_t));
}
diff --git a/mach/msg-destroy.c b/mach/msg-destroy.c
index 19137baa62..8640c965bd 100644
--- a/mach/msg-destroy.c
+++ b/mach/msg-destroy.c
@@ -108,11 +108,17 @@ __mach_msg_destroy (mach_msg_header_t *msg)
addr = is_inline ? saddr : * (vm_offset_t *) saddr;
 
if (MACH_MSG_TYPE_PORT_ANY(name)) {
-   mach_port_t *ports = (mach_port_t *) addr;
mach_msg_type_number_t i;
 
-   for (i = 0; i < number; i++)
-   mach_msg_destroy_port(*ports++, name);
+   if (is_inline) {
+   mach_port_name_inlined_t *inlined_ports = 
(mach_port_name_inlined_t *)addr;
+   for (i = 0; i < number; i++)
+   mach_msg_destroy_port(inlined_ports[i].name, name);
+   } else {
+   mach_port_t *ports = (mach_port_t *) addr;
+   for (i = 0; i < number; i++)
+   mach_msg_destroy_port(ports[i], name);
+   }
}
 
if (is_inline) {
-- 
2.39.2




[PATCH mig] x86_64: adapt MiG generated stubs to use mach_port_name_inlined_t for inlined port rights.

2023-11-24 Thread Flavio Cruz
For i686, we just change the code to use mach_port_name_inlined_t when
defining the types. This is a no-op.

For x86_64, there's a few things that are different:
- In the server code, the server handler can get inlined ports and the
  array will be resized and cast as an array of mach_port_name_t. Output
  parameters have a similar treatment where the inlined array in the
  output is used as an array of mach_port_name_t but resized to look like
  a mach_port_name_inlined_t.
- In the user side, we follow the same approach. Input ports as arrays
  of mach_port_name_t are expanded into an array of mach_port_name_inlined_t.
  Output ports are then converted back into an array of
  mach_port_name_inlined_t so that they fit into the expected message
  format.

Essentially, regardless of whether port rights are inline or out of
line, user interfaces and server stubs always receive an array of port
rights, not mach_port_name_inlined_t. However, inlined port rights will
be exchanged using mach_port_name_inlined_t.
---
 cpu.sym   |   1 +
 global.c  |   4 +-
 parser.y  |   4 --
 routine.c |   6 +++
 server.c  | 155 +-
 type.c|  36 -
 type.h|   5 ++
 user.c| 123 ---
 utils.c   |  28 +++---
 9 files changed, 271 insertions(+), 91 deletions(-)

diff --git a/cpu.sym b/cpu.sym
index bee12f0..1ac2fae 100644
--- a/cpu.sym
+++ b/cpu.sym
@@ -105,6 +105,7 @@ expr sizeof(float)  sizeof_float
 expr sizeof(double)sizeof_double
 expr sizeof(uintptr_t) sizeof_uintptr_t
 expr sizeof(intptr_t)  sizeof_intptr_t
+expr (sizeof(uintptr_t)*8) sizeof_uintptr_t_in_bits
 expr sizeof(mach_msg_header_t) sizeof_mach_msg_header_t
 expr sizeof(mach_msg_type_long_t)  sizeof_mach_msg_type_long_t
 expr sizeof(mach_msg_type_t)   sizeof_mach_msg_type_t
diff --git a/global.c b/global.c
index 0ef1dca..bac667c 100644
--- a/global.c
+++ b/global.c
@@ -65,8 +65,8 @@ string_t InternalHeaderFileName = strNULL;
 string_t UserFileName = strNULL;
 string_t ServerFileName = strNULL;
 
-size_t port_size = port_name_size;
-size_t port_size_in_bits = port_name_size_in_bits;
+size_t port_size = sizeof_uintptr_t;
+size_t port_size_in_bits = sizeof_uintptr_t_in_bits;
 size_t complex_alignof = desired_complex_alignof;
 
 void
diff --git a/parser.y b/parser.y
index cac3379..5a73af8 100644
--- a/parser.y
+++ b/parser.y
@@ -210,10 +210,6 @@ Subsystem  :   SubsystemStart SubsystemMods
   IsKernelUser ? ", KernelUser" : "",
   IsKernelServer ? ", KernelServer" : "");
 }
-if (IsKernelUser || IsKernelServer) {
-port_size = vm_offset_size;
-port_size_in_bits = vm_offset_size_in_bits;
-}
 init_type();
 }
;
diff --git a/routine.c b/routine.c
index 3ae9298..8909f4d 100644
--- a/routine.c
+++ b/routine.c
@@ -517,6 +517,12 @@ rtAugmentArgKind(argument_t *arg)
 {
arg->argKind = akAddFeature(arg->argKind, akbPointer);
 }
+if (akCheck(arg->argKind, akbSendRcv) &&
+IS_64BIT_ABI &&
+it->itUserlandPort &&
+   akCheck(arg->argKind, akbIndefinite)) {
+   arg->argKind = akAddFeature(arg->argKind, akbPointer);
+}
 }
 
 /* arg->argType may be NULL in this function */
diff --git a/server.c b/server.c
index 00ca3f2..b95e4d0 100644
--- a/server.c
+++ b/server.c
@@ -455,10 +455,27 @@ WriteTypeCheck(FILE *file, const argument_t *arg)
arg->argRequestPos, arg->argTTName,
arg->argLongForm ? "l" : "",
it->itNumber);
-   fprintf(file, "\t(In%dP->%s.msgt%s_size != %d)))\n",
-   arg->argRequestPos, arg->argTTName,
-   arg->argLongForm ? "l" : "",
-   it->itSize);
+   if (IS_64BIT_ABI && it->itUserlandPort && arg->argLongForm) {
+   /* 64 bit inlined ports are 8 bytes long but we use 
mach_port_name_t when passing them out of line. */
+   fprintf(file, "\t(In%dP->%s.msgtl_size != %d && 
In%dP->%s.msgtl_header.msgt_inline == TRUE) || \n",
+   arg->argRequestPos,
+   arg->argTTName,
+   it->itSize,
+   arg->argRequestPos,
+   arg->argTTName);
+   fprintf(file, "\t(In%dP->%s.msgtl_size != %d && 
In%dP->%s.msgtl_header.msgt_inline == FALSE)",
+   arg->argRequestPos,
+   arg->argTTName,
+   port_name_size_in_bits,
+   arg->argRequestPos,
+   arg->argTTName);
+   } else {
+   fprintf(file, "\t(In%dP->%s.msgt%s_size != %d)",
+   arg->argRequestPos, arg->argTTName,
+   arg->argLongForm ? "l" : "",
+   it->itSize);
+   }
+   fprintf(file, "))\n");
 }
 WriteMsgError(file, 

[PATCH gnumach] x86_64: Support 8 byte inlined port rights to avoid message resizing.

2023-11-24 Thread Flavio Cruz
If a port is inlined in a message, the user has to use
mach_port_name_inlined_t to define each port. Out of line memory
continues to use mach_port_name_t since that memory has to be copied to
the kernel anyway.

Both copyinmsg and copyoutmsg can be reduced to nothing (if we ignore
USER32) as a follow up but kept this patch simple for ease of review.
---
 i386/i386/copy_user.h  | 12 -
 include/mach/message.h | 18 +
 x86_64/copy_user.c | 61 +-
 3 files changed, 77 insertions(+), 14 deletions(-)

diff --git a/i386/i386/copy_user.h b/i386/i386/copy_user.h
index 5cdbfa80..3d1c7278 100644
--- a/i386/i386/copy_user.h
+++ b/i386/i386/copy_user.h
@@ -87,16 +87,14 @@ static inline int copyout_port(const mach_port_t *kaddr, 
mach_port_name_t *uaddr
 #endif /* __x86_64__ */
 }
 
-// XXX we could add another field to kmsg to store the user-side size, but 
then we
-// should check if we can  obtain it for rpc and notifications originating from
-// the kernel
-#ifndef __x86_64__
+#if defined(__x86_64__) && defined(USER32)
+/* For 32 bit userland, kernel and user land messages are not the same size. */
+size_t msg_usize(const mach_msg_header_t *kmsg);
+#else
 static inline size_t msg_usize(const mach_msg_header_t *kmsg)
 {
   return kmsg->msgh_size;
 }
-#else /* __x86_64__ */
-size_t msg_usize(const mach_msg_header_t *kmsg);
-#endif /* __x86_64__ */
+#endif /* __x86_64__ && USER32 */
 
 #endif /* COPY_USER_H */
diff --git a/include/mach/message.h b/include/mach/message.h
index 816d257a..472e7251 100644
--- a/include/mach/message.h
+++ b/include/mach/message.h
@@ -221,6 +221,24 @@ typedef unsigned int mach_msg_type_name_t;
 typedef unsigned int mach_msg_type_size_t;
 typedef natural_t  mach_msg_type_number_t;
 
+/**
+ * Structure used for inlined port rights in messages.
+ *
+ * We use this to avoid having to perform message resizing in the kernel
+ * since userspace port rights might be smaller than kernel ports in 64 bit
+ * architectures.
+ */
+typedef struct {
+union {
+mach_port_name_t name;
+#ifdef KERNEL
+mach_port_t kernel_port;
+#else
+uintptr_t kernel_port_do_not_use;
+#endif  /* KERNEL */
+};
+} mach_port_name_inlined_t;
+
 typedef struct  {
 #ifdef __x86_64__
 /*
diff --git a/x86_64/copy_user.c b/x86_64/copy_user.c
index 0d3f301b..4efe833e 100644
--- a/x86_64/copy_user.c
+++ b/x86_64/copy_user.c
@@ -265,8 +265,15 @@ static inline int copyout_unpack_msg_type(vm_offset_t 
kaddr,
   mach_msg_type_size_t orig_size = kmtl->msgtl_size;
   int ret;
 
-  if (MACH_MSG_TYPE_PORT_ANY(kmtl->msgtl_name))
+  if (MACH_MSG_TYPE_PORT_ANY(kmtl->msgtl_name)) {
+#ifdef USER32
 kmtl->msgtl_size = bytes_to_descsize(sizeof(mach_port_name_t));
+#else
+/* 64 bit ABI uses mach_port_name_inlined_t for inlined ports. */
+if (!kmt->msgt_inline)
+  kmtl->msgtl_size = bytes_to_descsize(sizeof(mach_port_name_t));
+#endif
+  }
   ret = copyout_mach_msg_type_long(kmtl, (void*)uaddr);
   kmtl->msgtl_size = orig_size;
   if (ret)
@@ -283,8 +290,15 @@ static inline int copyout_unpack_msg_type(vm_offset_t 
kaddr,
   mach_msg_type_size_t orig_size = kmt->msgt_size;
   int ret;
 
-  if (MACH_MSG_TYPE_PORT_ANY(kmt->msgt_name))
+  if (MACH_MSG_TYPE_PORT_ANY(kmt->msgt_name)) {
+#ifdef USER32
 kmt->msgt_size = bytes_to_descsize(sizeof(mach_port_name_t));
+#else
+/* 64 bit ABI uses mach_port_name_inlined_t for inlined ports. */
+if (!kmt->msgt_inline)
+  kmt->msgt_size = bytes_to_descsize(sizeof(mach_port_name_t));
+#endif
+  }
   ret = copyout_mach_msg_type(kmt, (void *)uaddr);
   kmt->msgt_size = orig_size;
   if (ret)
@@ -299,8 +313,10 @@ static inline int copyout_unpack_msg_type(vm_offset_t 
kaddr,
   return 0;
 }
 
+#ifdef USER32
 /*
- * Compute the user-space size of a message still in the kernel.
+ * Compute the user-space size of a message still in the kernel when processing
+ * messages from 32bit userland.
  * The message may be originating from userspace (in which case we could
  * optimize this by keeping the usize around) or from kernel space (we could
  * optimize if the message structure is fixed and known in advance).
@@ -333,7 +349,8 @@ size_t msg_usize(const mach_msg_header_t *kmsg)
 {
   if (MACH_MSG_TYPE_PORT_ANY(name))
 {
-  saddr += sizeof(mach_port_t) * number;
+  const vm_size_t length = sizeof(mach_port_t) * number;
+  saddr += length;
   usize += sizeof(mach_port_name_t) * number;
 }
   else
@@ -355,6 +372,7 @@ size_t msg_usize(const mach_msg_header_t *kmsg)
 }
   return usize;
 }
+#endif /* USER32 */
 
 /*
  * Expand the msg header and, if required, the msg body (ports, pointers)
@@ -423,6 +441,8 @@ int copyinmsg (const void *userbuf, void *kernelbuf, const 
size_t 

Patch series to avoid message resizing for x86_64

2023-11-24 Thread Flavio Cruz
Hello, this patch series updates the RPC ABI so that inlined port rights
are always passed as mach_port_name_inlined_t which is as big as a
kernel port pointer. This avoids message resizing for x86_64 in the
kernel. Out of line port rights are unchanged. A future patch will
simplify copyinmsg/copyoutmsg for 64bit userland in gnumach.

The major changes here happen in MiG. The interface to the user stubs
and server handlers is unchanged but MiG generates special code to
ensure we can convert between arrays of mach_port_name_inlined_t and
mach_port_name_t, depending on the situation. We introduce
itUserlandPort to identify userland port rights and drive code
generation.

A few small changes were required for glibc and the hurd servers but
overall it's pretty minor, which is evidence that this approach makes
sense as MiG does the heavy lifting.

For x86_64, I tested this with a simple initrd that boots up with the core 
servers
and up to a bash shell. I didn't test if a full system works with rumpdisk
or with networking. Stub diffs are provided in 
https://gist.github.com/flavioc/300ca3d8edbf7126abe22f01021df03f

For i686, I didn't see any problems with a cross-built system.
The diff in the autogenerated code is minimal here.





[PATCH glibc] Remove untyped mach RPC code.

2023-11-18 Thread Flavio Cruz
Existing MiG does not support untyped messages and the Hurd will
continue to use typed messages for the foreseeable future.
---
 hurd/hurdfault.c   |  4 ---
 hurd/intr-msg.c| 69 --
 mach/msg-destroy.c | 64 --
 mach/msgserver.c   |  4 ---
 4 files changed, 141 deletions(-)

diff --git a/hurd/hurdfault.c b/hurd/hurdfault.c
index dae889a9..1578b88e 100644
--- a/hurd/hurdfault.c
+++ b/hurd/hurdfault.c
@@ -115,10 +115,6 @@ _hurdsig_fault_catch_exception_raise_state_identity
 #endif
 
 
-#ifdef NDR_CHAR_ASCII  /* OSF Mach flavors have different names.  */
-# define mig_reply_header_tmig_reply_error_t
-#endif
-
 static void
 faulted (void)
 {
diff --git a/hurd/intr-msg.c b/hurd/intr-msg.c
index 737bfe0f..24184f82 100644
--- a/hurd/intr-msg.c
+++ b/hurd/intr-msg.c
@@ -25,10 +25,6 @@
 
 #include "intr-msg.h"
 
-#ifdef NDR_CHAR_ASCII  /* OSF Mach flavors have different names.  */
-# define mig_reply_header_tmig_reply_error_t
-#endif
-
 error_t
 _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
 mach_msg_option_t option,
@@ -45,11 +41,7 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
 
   struct clobber
   {
-#ifdef NDR_CHAR_ASCII
-NDR_record_t ndr;
-#else
 mach_msg_type_t type;
-#endif
 error_t err;
   };
   union msg
@@ -59,11 +51,7 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
 struct
 {
   mach_msg_header_t header;
-#ifdef NDR_CHAR_ASCII
-  NDR_record_t ndr;
-#else
   mach_msg_type_t type;
-#endif
   int code;
 } check;
 struct
@@ -171,7 +159,6 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
}
   if (msg->msgh_bits & MACH_MSGH_BITS_COMPLEX)
{
-#ifndef MACH_MSG_PORT_DESCRIPTOR
  /* Check for MOVE_SEND rights in the message.  These hold refs
 that we need to release in case the message is in fact never
 re-sent later.  Since it might in fact be re-sent, we turn
@@ -243,62 +230,6 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
  ty = (void *) data + sizeof (void *);
}
}
-#else  /* Untyped Mach IPC flavor. */
- mach_msg_body_t *body = (void *) (msg + 1);
- mach_msg_descriptor_t *desc = (void *) (body + 1);
- mach_msg_descriptor_t *desc_end = desc + body->msgh_descriptor_count;
- for (; desc < desc_end; ++desc)
-   switch (desc->type.type)
- {
- case MACH_MSG_PORT_DESCRIPTOR:
-   switch (desc->port.disposition)
- {
- case MACH_MSG_TYPE_MOVE_SEND:
-   __mach_port_deallocate (mach_task_self (),
-   desc->port.name);
-   desc->port.disposition = MACH_MSG_TYPE_COPY_SEND;
-   break;
- case MACH_MSG_TYPE_COPY_SEND:
- case MACH_MSG_TYPE_MOVE_RECEIVE:
-   break;
- default:
-   assert (! "unexpected port type in interruptible RPC");
- }
-   break;
- case MACH_MSG_OOL_DESCRIPTOR:
-   if (desc->out_of_line.deallocate)
- __vm_deallocate (__mach_task_self (),
-  (vm_address_t) desc->out_of_line.address,
-  desc->out_of_line.size);
-   break;
- case MACH_MSG_OOL_PORTS_DESCRIPTOR:
-   switch (desc->ool_ports.disposition)
- {
- case MACH_MSG_TYPE_MOVE_SEND:
-   {
- mach_msg_size_t i;
- const mach_port_t *ports = desc->ool_ports.address;
- for (i = 0; i < desc->ool_ports.count; ++i)
-   __mach_port_deallocate (__mach_task_self (), ports[i]);
- desc->ool_ports.disposition = MACH_MSG_TYPE_COPY_SEND;
- break;
-   }
- case MACH_MSG_TYPE_COPY_SEND:
- case MACH_MSG_TYPE_MOVE_RECEIVE:
-   break;
- default:
-   assert (! "unexpected port type in interruptible RPC");
- }
-   if (desc->ool_ports.deallocate)
- __vm_deallocate (__mach_task_self (),
-  (vm_address_t) desc->ool_ports.address,
-  desc->ool_ports.count
-  * sizeof (mach_port_t));
-   break;
- default:
-   assert (! "unexpected descriptor type in interruptible RPC");
- }
-#endif
}
   break;
 
diff --git a/mach/msg-destroy.c b/mach/msg-destroy.c
index 0a8b46c8..19137baa 100644
--- a/mach/msg-destroy.c
+++ b/mach/msg-destroy.c
@@ -71,69 +71,6 @@ __mach_msg_destroy (mach_msg_header_t *msg)
 

[PATCH hurd] libfshelp: type check messages using the full mach_msg_type_t so that it works on x86_64.

2023-11-18 Thread Flavio Cruz
---
 libfshelp/start-translator-long.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libfshelp/start-translator-long.c 
b/libfshelp/start-translator-long.c
index 0d6c574..0b16e7d 100644
--- a/libfshelp/start-translator-long.c
+++ b/libfshelp/start-translator-long.c
@@ -110,7 +110,7 @@ service_fsys_startup (fshelp_open_fn_t underlying_open_fn, 
void *cookie,
 {
   union
   {
-uint32_t word;
+uintptr_t word;
mach_msg_type_t type;
   } t, c;
   t.type = *type;
-- 
2.39.2




[PATCH glibc] _hurd_intr_rpc_mach_msg: handle message iteration correctly.

2023-11-18 Thread Flavio Cruz
The `ty` pointer is only set at the end of the loop so that
`msgtl_header.msgt_inline` and `msgtl_header.msgt_deallocate` remain
valid. Also, when deallocating memory, we use the length from the
message directly rather than hard coding mach_port_t since we want to
deallocate any kind of OOL data.
---
 hurd/intr-msg.c | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/hurd/intr-msg.c b/hurd/intr-msg.c
index 98f588f2..737bfe0f 100644
--- a/hurd/intr-msg.c
+++ b/hurd/intr-msg.c
@@ -186,12 +186,14 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
  mach_msg_type_size_t size;
  mach_msg_type_number_t number;
 
- inline void clean_ports (mach_port_t *ports, int dealloc)
+ inline void clean_ports_and_memory (char *data, const vm_size_t 
length,
+   int dealloc)
{
  mach_msg_type_number_t i;
  switch (name)
{
case MACH_MSG_TYPE_MOVE_SEND:
+ mach_port_t *ports = (mach_port_t *) data;
  for (i = 0; i < number; i++)
__mach_port_deallocate (__mach_task_self (), *ports++);
  if (ty->msgtl_header.msgt_longform)
@@ -207,40 +209,38 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
assert (! "unexpected port type in interruptible RPC");
}
  if (dealloc)
-   __vm_deallocate (__mach_task_self (),
-(vm_address_t) ports,
-number * sizeof (mach_port_t));
+   __vm_deallocate (__mach_task_self (), (vm_address_t) data, 
length);
}
 
+ char *data;
  if (ty->msgtl_header.msgt_longform)
{
  name = ty->msgtl_name;
  size = ty->msgtl_size;
  number = ty->msgtl_number;
- ty = (void *) ty + sizeof (mach_msg_type_long_t);
+ data = (char *) ty + sizeof (mach_msg_type_long_t);
}
  else
{
  name = ty->msgtl_header.msgt_name;
  size = ty->msgtl_header.msgt_size;
  number = ty->msgtl_header.msgt_number;
- ty = (void *) ty + sizeof (mach_msg_type_t);
+ data = (char *) ty + sizeof (mach_msg_type_t);
}
 
+ const vm_size_t length = ((number * size) + 7) >> 3;
  if (ty->msgtl_header.msgt_inline)
{
  /* Calculate length of data in bytes.  */
- const vm_size_t length = ((number * size) + 7) >> 3;
- clean_ports ((void *) ty, 0);
+ clean_ports_and_memory (data, length, 0);
  /* Move to the next argument.  */
- ty = (void *) PTR_ALIGN_UP ((char *) ty + length,
- __alignof__ (uintptr_t));
+ ty = (void *) PTR_ALIGN_UP (data + length, __alignof__ 
(uintptr_t));
}
  else
{
- clean_ports (*(void **) ty,
+ clean_ports_and_memory (*(void **) data, length,
   ty->msgtl_header.msgt_deallocate);
- ty = (void *) ty + sizeof (void *);
+ ty = (void *) data + sizeof (void *);
}
}
 #else  /* Untyped Mach IPC flavor. */
-- 
2.39.2




[PATCH gnumach] Fix assertion for i686 since mach_port_name_t and mach_port_t have the same size

2023-11-06 Thread Flavio Cruz
---
 ipc/ipc_kmsg.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c
index 1b98445d..fb8de249 100644
--- a/ipc/ipc_kmsg.c
+++ b/ipc/ipc_kmsg.c
@@ -2385,7 +2385,8 @@ ipc_kmsg_copyout_body(
/* first allocate memory in the map */
uint64_t allocated = length;
 
-   assert(sizeof(mach_port_name_t) < 
sizeof(mach_port_t));
+   _Static_assert(sizeof(mach_port_name_t) <= 
sizeof(mach_port_t),
+   "Size of mach_port_t should be 
equal or larger than mach_port_name_t.");
allocated -= (sizeof(mach_port_t) - 
sizeof(mach_port_name_t)) * number;
 
kr = vm_allocate(map, , allocated, TRUE);
-- 
2.39.2




[PATCH glibc] Update BAD_TYPECHECK to work on x86_64

2023-11-05 Thread Flavio Cruz
---
 sysdeps/mach/mach_rpc.h | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/sysdeps/mach/mach_rpc.h b/sysdeps/mach/mach_rpc.h
index 152f057ca7..ed81403be6 100644
--- a/sysdeps/mach/mach_rpc.h
+++ b/sysdeps/mach/mach_rpc.h
@@ -20,11 +20,8 @@
 
 /* Macro used by MIG to cleanly check the type.  */
 #define BAD_TYPECHECK(type, check) __glibc_unlikely (({\
-  union { mach_msg_type_t t; uint32_t w; } _t, _c; \
+  union { mach_msg_type_t t; uintptr_t w; } _t, _c;\
   _t.t = *(type); _c.t = *(check);_t.w != _c.w; }))
 
-/* TODO: add this assertion for x86_64.  */
-#ifndef __x86_64__
-_Static_assert (sizeof (uint32_t) == sizeof (mach_msg_type_t),
-"mach_msg_type_t needs to be the same size as uint32_t");
-#endif
+_Static_assert (sizeof (uintptr_t) == sizeof (mach_msg_type_t),
+"mach_msg_type_t needs to be the same size as uintptr_t");
-- 
2.39.2




[PATCH incubator/dde] Use designated initializers when defining mach_msg_type_t in libmachdevdde

2023-08-10 Thread Flavio Cruz
This avoids assuming a specific field order in mach_msg_type_t (see
https://git.savannah.gnu.org/cgit/hurd/gnumach.git/commit/device/net_io.c?id=50b744c4c2877dfbec54dc7bdae0d141e34c17c3
for a similar change in gnumach).
---
 libmachdevdde/net.c | 26 +-
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/libmachdevdde/net.c b/libmachdevdde/net.c
index 193421160..25c08cd35 100644
--- a/libmachdevdde/net.c
+++ b/libmachdevdde/net.c
@@ -105,23 +105,23 @@ static struct machdev_device_emulation_ops 
linux_net_emulation_ops;
 
 static mach_msg_type_t header_type = 
 {
-  MACH_MSG_TYPE_BYTE,
-  8,
-  NET_HDW_HDR_MAX,
-  TRUE,
-  FALSE,
-  FALSE,
-  0
+  .msgt_name = MACH_MSG_TYPE_BYTE,
+  .msgt_size = 8,
+  .msgt_number = NET_HDW_HDR_MAX,
+  .msgt_inline = TRUE,
+  .msgt_longform = FALSE,
+  .msgt_deallocate = FALSE,
+  .msgt_unused = 0
 };
 
 static mach_msg_type_t packet_type = 
 {
-  MACH_MSG_TYPE_BYTE,  /* name */
-  8,   /* size */
-  0,   /* number */
-  TRUE,/* inline */
-  FALSE,   /* longform */
-  FALSE/* deallocate */
+  .msgt_name = MACH_MSG_TYPE_BYTE,
+  .msgt_size = 8,
+  .msgt_number = 0,
+  .msgt_inline = TRUE,
+  .msgt_longform = FALSE,
+  .msgt_deallocate = FALSE
 };
 
 static struct net_data *search_nd (struct net_device *dev)
-- 
2.39.2




[PATCH hurd] Check for file_utimens since that's the correct RPC for changing access/modification times

2023-06-13 Thread Flavio Cruz
libtrivfs/nfsd/fakeroot can now make the call to the underlying
translators.
---
 configure.ac | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 44aa69d7..452fe1fd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -155,7 +155,7 @@ AC_CHECK_FUNCS(file_exec_paths exec_exec_paths 
_hurd_exec_paths)
 AC_CHECK_FUNCS(_hurd_libc_proc_init)
 
 # Compatibility with glibc < 2.28
-AC_CHECK_FUNCS(file_futimens)
+AC_CHECK_FUNCS(file_utimens)
 AC_DEFINE([UTIME_NOW],[-1])
 AC_DEFINE([UTIME_OMIT],[-2])
 
-- 
2.39.2




[PATCH hurd] Replace msgh_kind with msgh_seqno

2023-06-12 Thread Flavio Cruz
msgh_kind is deprecated and is an alias to msgh_seqno.
---
 eth-multiplexer/vdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/eth-multiplexer/vdev.c b/eth-multiplexer/vdev.c
index f441803d..62042ee6 100644
--- a/eth-multiplexer/vdev.c
+++ b/eth-multiplexer/vdev.c
@@ -276,7 +276,7 @@ deliver_msg(struct net_rcv_msg *msg, struct vether_device 
*vdev)
   msg->msg_hdr.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0);
   /* remember message sizes must be rounded up */
   msg->msg_hdr.msgh_local_port = MACH_PORT_NULL;
-  msg->msg_hdr.msgh_kind = MACH_MSGH_KIND_NORMAL;
+  msg->msg_hdr.msgh_seqno = 0;
   msg->msg_hdr.msgh_id = NET_RCV_MSG_ID;
 
   if_port_list = >port_list.if_rcv_port_list;
-- 
2.39.2




[PATCH gnumach] Update the 64bit RPC ABI to be simpler (v2)

2023-06-12 Thread Flavio Cruz
* Make full use of the 8 bytes available in mach_msg_type_t by moving
  into the unused 4 bytes. This allows us to use 32bits for
  mach_msg_type_number_t whether we use the longform or not.
* Make mach_msg_type_long_t exactly the same as mach_msg_type_t.
  Updating MiG is strongly encouraged since it will generate better code
  to handle this new format.

After this change, any compatibility with compiled binaries for Hurd x86_64
will break since the message format is different. However, the new
schema simplifies the overall ABI, without having "holes" and also
avoids the need to have a 16 byte mach_msg_type_long_t.

Was able to boot a basic system up to a bash shell.
---
 include/mach/message.h | 52 ++---
 ipc/ipc_kmsg.c |  4 ++
 x86_64/copy_user.c | 88 ++
 3 files changed, 123 insertions(+), 21 deletions(-)

diff --git a/include/mach/message.h b/include/mach/message.h
index 0eab9d41..2177343a 100644
--- a/include/mach/message.h
+++ b/include/mach/message.h
@@ -222,6 +222,30 @@ typedef unsigned int mach_msg_type_size_t;
 typedef natural_t  mach_msg_type_number_t;
 
 typedef struct  {
+#ifdef __x86_64__
+/*
+ * For 64 bits, this struct is 8 bytes long so we
+ * can pack the same amount of information as mach_msg_type_long_t.
+ * Note that for 64 bit userland, msgt_size only needs to be 8 bits long
+ * but for kernel compatibility with 32 bit userland we allow it to be
+ * 16 bits long.
+ *
+ * Effectively, we don't need mach_msg_type_long_t but we are keeping it
+ * for a while to make the code similar between 32 and 64 bits.
+ *
+ * We also keep the msgt_longform bit around simply because it makes it
+ * very easy to convert messages from a 32 bit userland into a 64 bit
+ * kernel. Otherwise, we would have to replicate some of the MiG logic
+ * internally in the kernel.
+ */
+unsigned int   msgt_inline : 1,
+   msgt_longform : 1,
+   msgt_deallocate : 1,
+   msgt_name : 8,
+   msgt_size : 16,
+   msgt_unused : 5;
+mach_msg_type_number_t   msgt_number;
+#else
 unsigned int   msgt_name : 8,
msgt_size : 8,
msgt_number : 12,
@@ -229,20 +253,38 @@ typedef struct  {
msgt_longform : 1,
msgt_deallocate : 1,
msgt_unused : 1;
-#ifdef __x86_64__
-/* TODO: We want to eventually use this in favor of mach_msg_type_long_t
- * as it makes the mach_msg protocol require only mach_msg_type_t. */
-mach_msg_type_number_t   unused_msgtl_number;
 #endif
 } __attribute__ ((aligned (__alignof__ (uintptr_t mach_msg_type_t;
 
-typedefstruct  {
+typedef struct {
+#ifdef __x86_64__
+union {
+/* On x86_64 this is equivalent to mach_msg_type_t so use
+ * union to overlay with the old field names.  */
+mach_msg_type_tmsgtl_header;
+struct {
+unsigned int   msgtl_inline : 1,
+msgtl_longform : 1,
+msgtl_deallocate : 1,
+msgtl_name : 8,
+msgtl_size : 16,
+msgtl_unused : 5;
+mach_msg_type_number_t   msgtl_number;
+};
+};
+#else
 mach_msg_type_tmsgtl_header;
 unsigned short msgtl_name;
 unsigned short msgtl_size;
 natural_t  msgtl_number;
+#endif
 } __attribute__ ((aligned (__alignof__ (uintptr_t mach_msg_type_long_t;
 
+#ifdef __x86_64__
+_Static_assert (sizeof (mach_msg_type_t) == sizeof (mach_msg_type_long_t),
+"mach_msg_type_t and mach_msg_type_long_t need to have the 
same size.");
+#endif
+
 /*
  * Known values for the msgt_name field.
  *
diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c
index 1988da45..d1c4675c 100644
--- a/ipc/ipc_kmsg.c
+++ b/ipc/ipc_kmsg.c
@@ -1343,9 +1343,11 @@ ipc_kmsg_copyin_body(
is_port = MACH_MSG_TYPE_PORT_ANY(name);
 
if ((is_port && (size != PORT_T_SIZE_IN_BITS)) ||
+#ifndef __x86_64__
(longform && ((type->msgtl_header.msgt_name != 0) ||
  (type->msgtl_header.msgt_size != 0) ||
  (type->msgtl_header.msgt_number != 0))) ||
+#endif
(((mach_msg_type_t*)type)->msgt_unused != 0) ||
(dealloc && is_inline)) {
ipc_kmsg_clean_partial(kmsg, taddr, FALSE, 0);
@@ -2833,9 +2835,11 @@ ipc_msg_print(mach_msg_header_t *msgh)
is_port = MACH_MSG_TYPE_PORT_ANY(name);
 
if ((is_port && (size != PORT_T_SIZE_IN_BITS)) ||
+#ifndef __x86_64__
(longform && ((type->msgtl_header.msgt_name != 0) ||
  (type->msgtl_header.msgt_size != 0) ||

[PATCH gnumach] copyinmsg: allow for the last message element to have msgt_number = 0.

2023-06-11 Thread Flavio Cruz
When copying messages from user space, some messages may have
mach_msg_type_t with msgt_number = 0 and no data after. This is a valid
message and we want to allow that.

I found this bug when testing "[PATCH gnumach] Update the
64bit RPC ABI to be simpler" and attempting to run a basic Hurd x86_64 that can 
start a
bash shell. When mach_msg_type_long_t is the same size as
mach_msg_type_t this bug happens quite frequently and prevents the
system from starting properly.
---
 x86_64/copy_user.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/x86_64/copy_user.c b/x86_64/copy_user.c
index f76e44c9..6ff50e12 100644
--- a/x86_64/copy_user.c
+++ b/x86_64/copy_user.c
@@ -332,7 +332,7 @@ int copyinmsg (const void *userbuf, void *kernelbuf, const 
size_t usize)
   if (usize > sizeof(mach_msg_user_header_t))
 {
   /* check we have at least space for an empty descryptor */
-  while (usaddr < (ueaddr - sizeof(mach_msg_user_type_t)))
+  while (usaddr <= (ueaddr - sizeof(mach_msg_user_type_t)))
 {
   vm_size_t user_amount, kernel_amount;
   mach_msg_type_name_t name;
@@ -401,7 +401,6 @@ int copyinmsg (const void *userbuf, void *kernelbuf, const 
size_t usize)
 }
 
   kmsg->msgh_size = sizeof(mach_msg_header_t) + ksaddr - (vm_offset_t)(kmsg + 
1);
-  kmsg->msgh_size = kmsg->msgh_size;
   return 0;
 }
 
-- 
2.39.2




[PATCH glibc] Fix build for hurd/thread-self.c for i386.

2023-05-21 Thread Flavio Cruz
We need to include hurd.h for libc_hidden_proto (__hurd_thread_self),
introduced in 
https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b44c1e12524bb5de0f93294a7c24c8e41c06bb75

This the error log:

In file included from :
./../include/libc-symbols.h:472:33: error: '__EI___hurd_thread_self' aliased to 
undefined symbol '__GI___hurd_thread_self'
  472 |   extern thread __typeof (name) __EI_##name \
  | ^
./../include/libc-symbols.h:468:3: note: in expansion of macro '__hidden_ver2'
  468 |   __hidden_ver2 (, local, internal, name)
  |   ^
./../include/libc-symbols.h:476:41: note: in expansion of macro '__hidden_ver1'
  476 | #  define hidden_def(name)  __hidden_ver1(__GI_##name, 
name, name);
  | ^
./../include/libc-symbols.h:557:32: note: in expansion of macro 'hidden_def'
  557 | # define libc_hidden_def(name) hidden_def (name)
  |^~
thread-self.c:27:1: note: in expansion of macro 'libc_hidden_def'
   27 | libc_hidden_def (__hurd_thread_self)
  | ^~~
---
 hurd/thread-self.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hurd/thread-self.c b/hurd/thread-self.c
index af013503bf..494a127aa5 100644
--- a/hurd/thread-self.c
+++ b/hurd/thread-self.c
@@ -16,6 +16,7 @@
License along with the GNU C Library; if not, see
.  */
 
+#include 
 #include 
 
 thread_t
-- 
2.39.2




[PATCH mig] Update code generation to handle the new 64 bit ABI

2023-05-16 Thread Flavio Cruz
Mostly, we don't set the fields that do not exist and avoid type
mismatching (like casting unsigned short to unsigned char for
msgt_name).

We also revamp type checking to compare mach_msg_type_t to uint64_t
instead of just uint32_t as we now use the whole structure.
---
 global.h |  2 ++
 utils.c  | 27 +++
 2 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/global.h b/global.h
index e3d42dd..11e772e 100644
--- a/global.h
+++ b/global.h
@@ -71,6 +71,8 @@ extern size_t port_size;
 extern size_t port_size_in_bits;
 extern size_t complex_alignof;
 
+#define IS_64BIT_ABI (desired_complex_alignof == 8)
+
 extern void more_global(void);
 
 #ifndef NULL
diff --git a/utils.c b/utils.c
index 6d6bb9e..6198144 100644
--- a/utils.c
+++ b/utils.c
@@ -78,7 +78,7 @@ WriteBogusDefines(FILE *file)
 
 fprintf(file, "#define BAD_TYPECHECK(type, check) mig_unlikely (({\\\n");
 fprintf(file,
-   "  union { mach_msg_type_t t; uint32_t w; } _t, _c;\\\n");
+   "  union { mach_msg_type_t t; uint%d_t w; } _t, _c;\\\n", 
desired_complex_alignof * 8);
 fprintf(file,
"  _t.t = *(type); _c.t = *(check);_t.w != _c.w; }))\n");
 }
@@ -358,11 +358,21 @@ static void
 WriteStaticLongDecl(FILE *file, const ipc_type_t *it,
dealloc_t dealloc, bool inname, identifier_t name)
 {
+const_string_t msgt_name = inname ? it->itInNameStr : it->itOutNameStr;
 fprintf(file, "\tconst mach_msg_type_long_t %s = {\n", name);
 fprintf(file, "\t\t.msgtl_header = {\n");
-fprintf(file, "\t\t\t.msgt_name =\t\t0,\n");
-fprintf(file, "\t\t\t.msgt_size =\t\t0,\n");
-fprintf(file, "\t\t\t.msgt_number =\t\t0,\n");
+if (IS_64BIT_ABI) {
+/* For the 64 bit ABI we don't really have mach_msg_type_long_t
+* so we fill mach_msg_type_long_t just like mach_msg_type_t.
+*/
+   fprintf(file, "\t\t\t.msgt_name =\t\t(unsigned char) %s,\n", 
msgt_name);
+   fprintf(file, "\t\t\t.msgt_size =\t\t%d,\n", it->itSize);
+   fprintf(file, "\t\t\t.msgt_number =\t\t%d,\n", it->itNumber);
+} else {
+   fprintf(file, "\t\t\t.msgt_name =\t\t0,\n");
+   fprintf(file, "\t\t\t.msgt_size =\t\t0,\n");
+   fprintf(file, "\t\t\t.msgt_number =\t\t0,\n");
+}
 fprintf(file, "\t\t\t.msgt_inline =\t\t%s,\n",
strbool(it->itInLine));
 fprintf(file, "\t\t\t.msgt_longform =\t\tTRUE,\n");
@@ -370,10 +380,11 @@ WriteStaticLongDecl(FILE *file, const ipc_type_t *it,
strdealloc(dealloc));
 fprintf(file, "\t\t\t.msgt_unused =\t\t0\n");
 fprintf(file, "\t\t},\n");
-fprintf(file, "\t\t.msgtl_name =\t(unsigned short) %s,\n",
-   inname ? it->itInNameStr : it->itOutNameStr);
-fprintf(file, "\t\t.msgtl_size =\t%d,\n", it->itSize);
-fprintf(file, "\t\t.msgtl_number =\t%d,\n", it->itNumber);
+if (!IS_64BIT_ABI) {
+fprintf(file, "\t\t.msgtl_name =\t(unsigned short) %s,\n", msgt_name);
+   fprintf(file, "\t\t.msgtl_size =\t%d,\n", it->itSize);
+   fprintf(file, "\t\t.msgtl_number =\t%d,\n", it->itNumber);
+}
 fprintf(file, "\t};\n");
 }
 
-- 
2.39.2




[PATCH gnumach] Update the 64bit RPC ABI to be simpler

2023-05-16 Thread Flavio Cruz
* Make full use of the 8 bytes available in mach_msg_type_t by moving
  into the unused 4 bytes. This allows us to use 32bits for
  mach_msg_type_number_t whether we use the longform or not.
* Make mach_msg_type_long_t exactly the same as mach_msg_type_t. I'm not
  changing any of the code but keeping the same interface using macros.
  Updating MiG is strongly encouraged since it will generate better code
  to handle this new format.

After this change, any compatibility with compiled binaries for Hurd x86_64
will break since the message format is different. However, the new
schema simplifies the overall ABI, without having "holes" and also
avoids the need to have a 16 byte mach_msg_type_long_t.

Tested with simple programs on pure 64 bit and 64/32 bit combinations.

---
Not too thrilled about the use of the macros for msgtl_name/size/number
but happy to hear about other alternatives. Potentially we could 
introduce accessors and update all the calls to use them.

Note that the follow up MiG patch is necessary to make this work.

 include/mach/message.h |  37 +--
 ipc/ipc_kmsg.c |   4 ++
 x86_64/copy_user.c | 100 -
 3 files changed, 115 insertions(+), 26 deletions(-)

diff --git a/include/mach/message.h b/include/mach/message.h
index 0eab9d41..d1783715 100644
--- a/include/mach/message.h
+++ b/include/mach/message.h
@@ -222,6 +222,30 @@ typedef unsigned int mach_msg_type_size_t;
 typedef natural_t  mach_msg_type_number_t;
 
 typedef struct  {
+#ifdef __x86_64__
+/*
+ * For 64 bits, this struct is 8 bytes long so we
+ * can pack the same amount of information as mach_msg_type_long_t.
+ * Note that for 64 bit userland, msgt_size only needs to be 8 bits long
+ * but for kernel compatibility with 32 bit userland we allow it to be
+ * 16 bits long.
+ *
+ * Effectively, we don't need mach_msg_type_long_t but we are keeping it
+ * for a while to make the code similar between 32 and 64 bits.
+ *
+ * We also keep the msgt_longform bit around simply because it makes it
+ * very easy to convert messages from a 32 bit userland into a 64 bit
+ * kernel. Otherwise, we would have to replicate some of the MiG logic
+ * internally in the kernel.
+ */
+unsigned int   msgt_inline : 1,
+   msgt_longform : 1,
+   msgt_deallocate : 1,
+   msgt_name : 8,
+   msgt_size : 16,
+   msgt_unused : 5;
+mach_msg_type_number_t   msgt_number;
+#else
 unsigned int   msgt_name : 8,
msgt_size : 8,
msgt_number : 12,
@@ -229,18 +253,23 @@ typedef struct  {
msgt_longform : 1,
msgt_deallocate : 1,
msgt_unused : 1;
-#ifdef __x86_64__
-/* TODO: We want to eventually use this in favor of mach_msg_type_long_t
- * as it makes the mach_msg protocol require only mach_msg_type_t. */
-mach_msg_type_number_t   unused_msgtl_number;
 #endif
 } __attribute__ ((aligned (__alignof__ (uintptr_t mach_msg_type_t;
 
+/* On x86_64 this is equivalent to mach_msg_type_t.  */
 typedefstruct  {
 mach_msg_type_tmsgtl_header;
+#ifdef __x86_64__
+/* Since we don't have these separate fields, we remap them
+ * into the fields from mach_msg_type_t. */
+#define msgtl_name msgtl_header.msgt_name
+#define msgtl_size msgtl_header.msgt_size
+#define msgtl_number msgtl_header.msgt_number
+#else
 unsigned short msgtl_name;
 unsigned short msgtl_size;
 natural_t  msgtl_number;
+#endif
 } __attribute__ ((aligned (__alignof__ (uintptr_t mach_msg_type_long_t;
 
 /*
diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c
index 1988da45..d1c4675c 100644
--- a/ipc/ipc_kmsg.c
+++ b/ipc/ipc_kmsg.c
@@ -1343,9 +1343,11 @@ ipc_kmsg_copyin_body(
is_port = MACH_MSG_TYPE_PORT_ANY(name);
 
if ((is_port && (size != PORT_T_SIZE_IN_BITS)) ||
+#ifndef __x86_64__
(longform && ((type->msgtl_header.msgt_name != 0) ||
  (type->msgtl_header.msgt_size != 0) ||
  (type->msgtl_header.msgt_number != 0))) ||
+#endif
(((mach_msg_type_t*)type)->msgt_unused != 0) ||
(dealloc && is_inline)) {
ipc_kmsg_clean_partial(kmsg, taddr, FALSE, 0);
@@ -2833,9 +2835,11 @@ ipc_msg_print(mach_msg_header_t *msgh)
is_port = MACH_MSG_TYPE_PORT_ANY(name);
 
if ((is_port && (size != PORT_T_SIZE_IN_BITS)) ||
+#ifndef __x86_64__
(longform && ((type->msgtl_header.msgt_name != 0) ||
  (type->msgtl_header.msgt_size != 0) ||
  (type->msgtl_header.msgt_number != 0))) ||
+#endif
(((mach_msg_type_t*)type)->msgt_unused != 

[PATCH gnumach] Fix task_info for TASK_THREAD_TIMES_INFO.

2023-05-16 Thread Flavio Cruz
We are checking for the existence of time_value64_t but we didn't add
that to the task_thread_times_info structure.
---
 include/mach/task_info.h | 6 ++
 kern/task.c  | 8 +++-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/include/mach/task_info.h b/include/mach/task_info.h
index 2631b04e..0e048c5e 100644
--- a/include/mach/task_info.h
+++ b/include/mach/task_info.h
@@ -97,10 +97,16 @@ typedef struct task_events_info 
*task_events_info_t;
   only accurate if suspended */
 
 struct task_thread_times_info {
+   /* Deprecated, please use user_time64 */
rpc_time_value_tuser_time;  /* total user run time for
   live threads */
+   /* Deprecated, please use system_time64 */
rpc_time_value_tsystem_time;/* total system run time for
   live threads */
+   time_value64_t  user_time64;/* total user run time for
+  live threads */
+   time_value64_t  system_time64;  /* total system run time for
+  live threads */
 };
 
 typedef struct task_thread_times_info  task_thread_times_info_data_t;
diff --git a/kern/task.c b/kern/task.c
index 9492b448..60ab4d73 100644
--- a/kern/task.c
+++ b/kern/task.c
@@ -887,8 +887,14 @@ kern_return_t task_info(
task_unlock(task);
TIME_VALUE64_TO_TIME_VALUE(_user_time, 
_info->user_time);
TIME_VALUE64_TO_TIME_VALUE(_system_time, 
_info->system_time);
+   if (*task_info_count >= TASK_THREAD_TIMES_INFO_COUNT) {
+   /* Copy new time_value64_t fields */
+   times_info->user_time64 = acc_user_time;
+   times_info->system_time64 = acc_system_time;
+   }
 
-   *task_info_count = TASK_THREAD_TIMES_INFO_COUNT;
+   if (*task_info_count > TASK_THREAD_TIMES_INFO_COUNT)
+ *task_info_count = TASK_THREAD_TIMES_INFO_COUNT;
break;
}
 
-- 
2.39.2




[PATCH glibc] Use TASK_THREAD_TIMES_INFO_COUNT when calling task_info with TASK_THREAD_TIMES_INFO

2023-05-16 Thread Flavio Cruz
This hasn't caused any problems yet but we are passing a pointer to struct
task_thread_times_info which can cause problems if we populate over the
existing size of the struct.
---
 sysdeps/mach/clock_gettime.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sysdeps/mach/clock_gettime.c b/sysdeps/mach/clock_gettime.c
index cc8c821a7f..be775ed2bb 100644
--- a/sysdeps/mach/clock_gettime.c
+++ b/sysdeps/mach/clock_gettime.c
@@ -62,7 +62,7 @@ __clock_gettime (clockid_t clock_id, struct timespec *ts)
time_value_add (, _time);
 
/* Live threads CPU time.  */
-   count = TASK_EVENTS_INFO_COUNT;
+   count = TASK_THREAD_TIMES_INFO_COUNT;
err = __task_info (__mach_task_self (), TASK_THREAD_TIMES_INFO,
   (task_info_t) , );
if (err)
-- 
2.39.2




[PATCH mig] Check that msgt_name is always smaller than 255.

2023-05-09 Thread Flavio Cruz
For the x86_64 ABI we want this to always fit into 1 byte. Even for
regular i686, msgt_name is always smaller than 25 (MACH_MSG_TYPE_LAST)
and we don't have plans to have more names.

Also throw an error if we deemed an RPC to be "TooLong" as that won't
work or work badly.

Tested by cross-compiling a basic Hurd system.
---
 type.c | 18 ++
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/type.c b/type.c
index 6158c14..253a194 100644
--- a/type.c
+++ b/type.c
@@ -323,19 +323,21 @@ itUseLong(const ipc_type_t *it)
 if ((it->itVarArray && !it->itInLine) || it->itIndefinite)
uselong = ShouldBeLong;
 
+/* Check that msgt_name fits into 1 byte as the x86_64 ABI requires it.
+   Note that MACH_MSG_TYPE_POLYMORPHIC is -1 hence it is ignored. */
 if (((it->itInName != MACH_MSG_TYPE_POLYMORPHIC) &&
 (it->itInName >= (1<<8))) ||
((it->itOutName != MACH_MSG_TYPE_POLYMORPHIC) &&
-(it->itOutName >= (1<<8))) ||
-   (it->itSize >= (1<<8)) ||
+(it->itOutName >= (1<<8 {
+error("Cannot have msgt_name greater than 255");
+uselong = TooLong;
+}
+
+   if ((it->itSize >= (1<<8)) ||
(it->itNumber >= (1<<12)))
uselong = MustBeLong;
 
-if (((it->itInName != MACH_MSG_TYPE_POLYMORPHIC) &&
-(it->itInName >= (1<<16))) ||
-   ((it->itOutName != MACH_MSG_TYPE_POLYMORPHIC) &&
-(it->itOutName >= (1<<16))) ||
-   (it->itSize >= (1<<16)))
+if (it->itSize >= (1<<16))
uselong = TooLong;
 
 return uselong;
@@ -416,7 +418,7 @@ itCheckDecl(identifier_t name, ipc_type_t *it)
 
 uselong = itUseLong(it);
 if (uselong == TooLong)
-   warn("%s: too big for mach_msg_type_long_t", name);
+   error("%s: too big for mach_msg_type_long_t", name);
 it->itLongForm = itCheckIsLong(it, it->itFlags,
   (int)uselong >= (int)ShouldBeLong, name);
 }
-- 
2.39.2




[PATCH glibc] Stop checking if MiG supports retcode.

2023-05-09 Thread Flavio Cruz
We already did the same change for Hurd
(https://git.savannah.gnu.org/cgit/hurd/hurd.git/commit/?id=ef5924402864ef049f40a39e73967628583bc1a4)

Due to MiG requiring the subsystem to be defined early in order to know the
size of a port, this was causing a division by zero error during ./configure.
We could have just move subsystem to the top of the snippet, however it is
simpler to just remove the check given that we have no plans to use some other
MiG anyway.

HAVE_MIG_RETCODE is removed completely since this will be a no-op either
way (compiling against old Hurd headers will work the same, new Hurd
headers will result in the same stubs since retcode is a no-op).
---
 config.h.in   |  3 ---
 sysdeps/mach/configure| 36 
 sysdeps/mach/configure.ac | 26 --
 3 files changed, 65 deletions(-)

diff --git a/config.h.in b/config.h.in
index c87008b6a9..44a34072a4 100644
--- a/config.h.in
+++ b/config.h.in
@@ -150,9 +150,6 @@
 /* Override abi-tags ABI version if necessary.  */
 #undef  __ABI_TAG_VERSION
 
-/* Mach/Hurd specific: define if mig supports the `retcode' keyword.  */
-#undef HAVE_MIG_RETCODE
-
 /* Mach specific: define if the `host_page_size' RPC is available.  */
 #undef HAVE_HOST_PAGE_SIZE
 
diff --git a/sysdeps/mach/configure b/sysdeps/mach/configure
index b08872b8bc..df20d8640f 100644
--- a/sysdeps/mach/configure
+++ b/sysdeps/mach/configure
@@ -485,40 +485,4 @@ if test $libc_cv_mach_i386_gdt = yes; then
 fi
 
 
-
-# See if mig groks `retcode'.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $MIG supports the 
retcode keyword" >&5
-$as_echo_n "checking whether $MIG supports the retcode keyword... " >&6; }
-if ${hurd_cv_mig_retcode+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat > conftest.defs <<\EOF
-#include 
-#include 
-subsystem foobar 1000;
-type reply_port_t = polymorphic | MACH_MSG_TYPE_PORT_SEND_ONCE
-   ctype: mach_port_t;
-simpleroutine foobar_reply (
-   reply_port: reply_port_t;
-   err: kern_return_t, RetCode);
-EOF
-if { ac_try='CC="${CC}" ${MIG-false} -n conftest.defs 1>&5'
-  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; }; then
-  hurd_cv_mig_retcode=yes
-else
-  hurd_cv_mig_retcode=no
-fi
-rm -f conftest*
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hurd_cv_mig_retcode" >&5
-$as_echo "$hurd_cv_mig_retcode" >&6; }
-if test $hurd_cv_mig_retcode = yes; then
-  $as_echo "#define HAVE_MIG_RETCODE 1" >>confdefs.h
-
-fi
-
 CPPFLAGS=$OLD_CPPFLAGS
diff --git a/sysdeps/mach/configure.ac b/sysdeps/mach/configure.ac
index 537677c1d7..869cc9f820 100644
--- a/sysdeps/mach/configure.ac
+++ b/sysdeps/mach/configure.ac
@@ -104,30 +104,4 @@ if test $libc_cv_mach_i386_gdt = yes; then
   AC_DEFINE([HAVE_I386_SET_GDT])
 fi
 
-dnl Swiped from hurd/aclocal.m4
-AC_DEFUN([hurd_MIG_RETCODE], [dnl
-# See if mig groks `retcode'.
-AC_CACHE_CHECK(whether $MIG supports the retcode keyword, hurd_cv_mig_retcode,
-[cat > conftest.defs <<\EOF
-#include 
-#include 
-subsystem foobar 1000;
-type reply_port_t = polymorphic | MACH_MSG_TYPE_PORT_SEND_ONCE
-   ctype: mach_port_t;
-simpleroutine foobar_reply (
-   reply_port: reply_port_t;
-   err: kern_return_t, RetCode);
-EOF
-if AC_TRY_COMMAND([CC="${CC}" ${MIG-false} -n conftest.defs 
1>_MESSAGE_LOG_FD]); then
-  hurd_cv_mig_retcode=yes
-else
-  hurd_cv_mig_retcode=no
-fi
-rm -f conftest*])
-if test $hurd_cv_mig_retcode = yes; then
-  AC_DEFINE(HAVE_MIG_RETCODE)
-fi])
-
-hurd_MIG_RETCODE
-
 CPPFLAGS=$OLD_CPPFLAGS
-- 
2.39.2




[PATCH hurd] Only use host_get_kernel_version and default_pager_paging_storage_new in x86_64.

2023-05-09 Thread Flavio Cruz
Also fixed the implementation of default_pager_paging_storage_new in proxy
def pager to call into default_pager_paging_storage_new.

We can fast track the simplification of the RPC ABI for x86_64 if we don't have
MACH_MSG_TYPE_STRING used in RPCs which forces msgt_size to use more than 8
bits.
---
 hurd/default_pager.defs |  4 
 mach-defpager/setup.c   | 10 ++
 proc/host.c |  3 +++
 sutils/swapon.c |  3 +++
 trans/proxy-defpager.c  | 30 +++---
 5 files changed, 39 insertions(+), 11 deletions(-)

diff --git a/hurd/default_pager.defs b/hurd/default_pager.defs
index 3ca34fc4..bb893d0a 100644
--- a/hurd/default_pager.defs
+++ b/hurd/default_pager.defs
@@ -69,6 +69,9 @@ skip; /* default_pager_paging_file */
 
 skip;  /* default_pager_register_fileserver */
 
+#ifdef __x86_64__
+skip;  /* default_pager_paging_storage */
+#else
 /* Deprecated RPC to add or remove an area of paging storage.
  * Was superseded in favor of default_pager_paging_storage_new which
  * uses the correct type for default_pager_filename_t using c_string.
@@ -80,6 +83,7 @@ routine default_pager_paging_storage(
   array[] of recnum_t;
name: default_pager_filename_t;
add : boolean_t);
+#endif
 
 /* This call is made on a memory object returned by default_pager_object_create
to fix the object's maximum size.  Any references to pages beyond the limit
diff --git a/mach-defpager/setup.c b/mach-defpager/setup.c
index b09642e3..e928dcc2 100644
--- a/mach-defpager/setup.c
+++ b/mach-defpager/setup.c
@@ -40,7 +40,7 @@ int page_aligned (vm_offset_t num)
 extern mach_port_t default_pager_default_port; /* default_pager.c */
 
 kern_return_t
-S_default_pager_paging_storage (mach_port_t pager,
+S_default_pager_paging_storage_new (mach_port_t pager,
mach_port_t device,
const recnum_t *runs, mach_msg_type_number_t 
nrun,
const_default_pager_filename_t name,
@@ -100,16 +100,18 @@ S_default_pager_paging_storage (mach_port_t pager,
   return 0;
 }
 
+#ifndef __x86_64__
 kern_return_t
-S_default_pager_paging_storage_new (mach_port_t pager,
+S_default_pager_paging_storage (mach_port_t pager,
mach_port_t device,
const recnum_t *runs, mach_msg_type_number_t 
nrun,
const_default_pager_filename_t name,
boolean_t add)
 {
-  return S_default_pager_paging_storage (pager,
-  device, runs, nrun, name, add);
+  return S_default_pager_paging_storage_new (pager, device, runs, nrun, name,
+ add);
 }
+#endif
 
 /* Called to read a page from backing store.  */
 int
diff --git a/proc/host.c b/proc/host.c
index e9f36f51..e2942f8e 100644
--- a/proc/host.c
+++ b/proc/host.c
@@ -364,11 +364,14 @@ initialize_version_info (void)
   server_versions_nalloc = 10;
 
   err = host_get_kernel_version (mach_host_self (), kv);
+#ifndef __x86_64__
+  /* We don't support host_kernel_version for x86_64. */
   if (err == MIG_BAD_ID)
 {
   /* Delete after some time. */
   err = host_kernel_version (mach_host_self (), kv);
 }
+#endif
   assert_backtrace (! err);
   /* Make sure the result is null-terminated, as the kernel doesn't
  guarantee it.  */
diff --git a/sutils/swapon.c b/sutils/swapon.c
index 30e2e2d6..6e3d64a4 100644
--- a/sutils/swapon.c
+++ b/sutils/swapon.c
@@ -411,11 +411,14 @@ swaponoff (const char *file, int add, int skipnotexisting)
 }
   err = default_pager_paging_storage_new (def_pager, store->port,
  runs, j, file, add);
+#ifndef __x86_64__
+  /* We don't support default_pager_paging_storage in 64 bits. */
   if (err == MIG_BAD_ID || err == EOPNOTSUPP)
 {
   err = default_pager_paging_storage (def_pager, store->port,
  runs, j, file, add);
 }
+#endif
 
   store_free (store);
 
diff --git a/trans/proxy-defpager.c b/trans/proxy-defpager.c
index 5d952546..e44db152 100644
--- a/trans/proxy-defpager.c
+++ b/trans/proxy-defpager.c
@@ -100,28 +100,44 @@ S_default_pager_object_pages (mach_port_t default_pager,
 }
 
 kern_return_t
-S_default_pager_paging_storage (mach_port_t default_pager,
+S_default_pager_paging_storage_new (mach_port_t default_pager,
mach_port_t device,
const recnum_t *runs, mach_msg_type_number_t 
nruns,
const_default_pager_filename_t name,
boolean_t add)
 {
-  return allowed (default_pager, O_WRITE)
-?: default_pager_paging_storage (real_defpager, dev_master,
-runs, nruns, name, add)
-?: mach_port_deallocate 

[PATCH hurd] Only use host_get_kernel_version and default_pager_paging_storage_new in x86_64.

2023-05-07 Thread Flavio Cruz
---
 hurd/default_pager.defs | 4 
 mach-defpager/setup.c   | 6 --
 proc/host.c | 3 +++
 sutils/swapon.c | 3 +++
 trans/proxy-defpager.c  | 6 --
 5 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/hurd/default_pager.defs b/hurd/default_pager.defs
index 3ca34fc4..bb893d0a 100644
--- a/hurd/default_pager.defs
+++ b/hurd/default_pager.defs
@@ -69,6 +69,9 @@ skip; /* default_pager_paging_file */
 
 skip;  /* default_pager_register_fileserver */
 
+#ifdef __x86_64__
+skip;  /* default_pager_paging_storage */
+#else
 /* Deprecated RPC to add or remove an area of paging storage.
  * Was superseded in favor of default_pager_paging_storage_new which
  * uses the correct type for default_pager_filename_t using c_string.
@@ -80,6 +83,7 @@ routine default_pager_paging_storage(
   array[] of recnum_t;
name: default_pager_filename_t;
add : boolean_t);
+#endif
 
 /* This call is made on a memory object returned by default_pager_object_create
to fix the object's maximum size.  Any references to pages beyond the limit
diff --git a/mach-defpager/setup.c b/mach-defpager/setup.c
index 087ede71..51dd6d84 100644
--- a/mach-defpager/setup.c
+++ b/mach-defpager/setup.c
@@ -40,7 +40,7 @@ int page_aligned (vm_offset_t num)
 extern mach_port_t default_pager_default_port; /* default_pager.c */
 
 kern_return_t
-S_default_pager_paging_storage (mach_port_t pager,
+S_default_pager_paging_storage_new (mach_port_t pager,
mach_port_t device,
const recnum_t *runs, mach_msg_type_number_t 
nrun,
const_default_pager_filename_t name,
@@ -100,8 +100,9 @@ S_default_pager_paging_storage (mach_port_t pager,
   return 0;
 }
 
+#ifndef __x86_64__
 kern_return_t
-S_default_pager_paging_storage_new (mach_port_t pager,
+S_default_pager_paging_storage (mach_port_t pager,
mach_port_t device,
const recnum_t *runs, mach_msg_type_number_t 
nrun,
const_default_pager_filename_t name,
@@ -110,6 +111,7 @@ S_default_pager_paging_storage_new (mach_port_t pager,
   return S_default_pager_paging_storage (pager,
   device, runs, nrun, name, add);
 }
+#endif
 
 /* Called to read a page from backing store.  */
 int
diff --git a/proc/host.c b/proc/host.c
index e78e70da..bd2462f2 100644
--- a/proc/host.c
+++ b/proc/host.c
@@ -364,11 +364,14 @@ initialize_version_info (void)
   server_versions_nalloc = 10;
 
   err = host_get_kernel_version (mach_host_self (), kv);
+#ifndef __x86_64__
+  /* We don't support host_kernel_version for x86_64. */
   if (err == MIG_BAD_ID)
 {
   /* Delete after some time. */
   err = host_kernel_version (mach_host_self (), kv);
 }
+#endif
   assert_backtrace (! err);
   /* Make sure the result is null-terminated, as the kernel doesn't
  guarantee it.  */
diff --git a/sutils/swapon.c b/sutils/swapon.c
index c965d8e2..a85d8a2d 100644
--- a/sutils/swapon.c
+++ b/sutils/swapon.c
@@ -411,11 +411,14 @@ swaponoff (const char *file, int add, int skipnotexisting)
 }
   err = default_pager_paging_storage_new (def_pager, store->port,
  runs, j, file, add);
+#ifndef __x86_64__
+  /* We don't support default_pager_paging_storage for x86_64. */
   if (err == MIG_BAD_ID || err == EOPNOTSUPP)
 {
   err = default_pager_paging_storage (def_pager, store->port,
  runs, j, file, add);
 }
+#endif
 
   store_free (store);
 
diff --git a/trans/proxy-defpager.c b/trans/proxy-defpager.c
index 5d952546..e34d272a 100644
--- a/trans/proxy-defpager.c
+++ b/trans/proxy-defpager.c
@@ -100,7 +100,7 @@ S_default_pager_object_pages (mach_port_t default_pager,
 }
 
 kern_return_t
-S_default_pager_paging_storage (mach_port_t default_pager,
+S_default_pager_paging_storage_new (mach_port_t default_pager,
mach_port_t device,
const recnum_t *runs, mach_msg_type_number_t 
nruns,
const_default_pager_filename_t name,
@@ -112,8 +112,9 @@ S_default_pager_paging_storage (mach_port_t default_pager,
 ?: mach_port_deallocate (mach_task_self (), device);
 }
 
+#ifndef __x86_64__
 kern_return_t
-S_default_pager_paging_storage_new (mach_port_t default_pager,
+S_default_pager_paging_storage (mach_port_t default_pager,
mach_port_t device,
const recnum_t *runs, mach_msg_type_number_t 
nruns,
const_default_pager_filename_t name,
@@ -122,6 +123,7 @@ S_default_pager_paging_storage_new (mach_port_t 
default_pager,
   return S_default_pager_paging_storage (default_pager,
   device, runs, nruns, name, add);
 }
+#endif

[PATCH gnumach] Remove host_kernel_version RPC for x86_64

2023-05-07 Thread Flavio Cruz
We can fast track the simplification of the RPC ABI for x86_64 if we don't have
MACH_MSG_TYPE_STRING used in RPCs which forces msgt_size to use more than 8
bits.
---
 include/mach/mach_host.defs |  4 
 kern/host.c | 10 ++
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/include/mach/mach_host.defs b/include/mach/mach_host.defs
index 90581cff..07383a57 100644
--- a/include/mach/mach_host.defs
+++ b/include/mach/mach_host.defs
@@ -161,6 +161,9 @@ routine task_get_assignment(
task: task_t;
out assigned_set: processor_set_name_t);
 
+#ifdef __x86_64__
+skip;
+#else
 /*
  * Get string describing current kernel version.
  * Deprecated, use host_get_kernel_version.
@@ -168,6 +171,7 @@ routine task_get_assignment(
 routinehost_kernel_version(
host: host_t;
out kernel_version  : kernel_version_t);
+#endif
 
 /*
  * Set priority for thread.
diff --git a/kern/host.c b/kern/host.c
index 50f58e9c..2db09154 100644
--- a/kern/host.c
+++ b/kern/host.c
@@ -205,7 +205,7 @@ kern_return_t   host_info(
  * wanted to know about what version of the kernel this is).
  */
 
-kern_return_t host_kernel_version(
+kern_return_t host_get_kernel_version(
const host_thost,
kernel_version_tout_version)
 {
@@ -219,13 +219,15 @@ kern_return_t host_kernel_version(
return KERN_SUCCESS;
 }
 
-/* Same as above */
-kern_return_t host_get_kernel_version(
+#ifndef __x86_64__
+/* Same as above, but does not exist for x86_64.  */
+kern_return_t host_kernel_version(
const host_thost,
kernel_version_tout_version)
 {
-   return host_kernel_version(host, out_version);
+   return host_get_kernel_version(host, out_version);
 }
+#endif
 
 /*
  * host_processor_sets:
-- 
2.39.2




[PATCH hurd] Stop checking if MiG supports retcode.

2023-05-07 Thread Flavio Cruz
Due to MiG requiring the subsystem to be defined early in order to know the
size of a port, this was causing a division by zero error during ./configure.
We could have just move subsystem to the top of the snippet, however it is
simpler to just remove the check given that we have no plans to use some other
MiG anyway.

We force RETURN_CODE_ARG to use retcode which is a no-op.
---
 aclocal.m4   | 24 
 configure.ac |  2 --
 hurd/hurd_types.defs |  5 -
 3 files changed, 31 deletions(-)

diff --git a/aclocal.m4 b/aclocal.m4
index 911dca2b..d54c7c2b 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -2,30 +2,6 @@ dnl These modifications are to allow for an empty cross 
compiler tree.
 dnl In the situation that cross-linking is impossible, the variable
 dnl `cross_linkable' will be substituted with "yes".
 
-dnl
-AC_DEFUN([hurd_MIG_RETCODE], [dnl
-# See if mig groks `retcode'.
-AC_CACHE_CHECK(whether $MIG supports the retcode keyword, hurd_cv_mig_retcode,
-[cat > conftest.defs <<\EOF
-#include 
-#include 
-subsystem foobar 1000;
-type reply_port_t = polymorphic | MACH_MSG_TYPE_PORT_SEND_ONCE
-   ctype: mach_port_t;
-simpleroutine foobar_reply (
-   reply_port: reply_port_t;
-   err: kern_return_t, RetCode);
-EOF
-if AC_TRY_COMMAND([CC="${CC}" ${MIG-false} -n conftest.defs 
1>_MESSAGE_LOG_FD()]); then
-  hurd_cv_mig_retcode=yes
-else
-  hurd_cv_mig_retcode=no
-fi
-rm -f conftest*])
-if test $hurd_cv_mig_retcode = yes; then
-  AC_DEFINE(HAVE_MIG_RETCODE)
-fi])
-
 dnl The following check is based on a similar check in GNU inetutils 1.4.0.
 dnl
 dnl hurd_LIB_NCURSESW -- check for, and configure, ncursesw
diff --git a/configure.ac b/configure.ac
index e913b3f3..9c80b96a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -113,8 +113,6 @@ fi
 dnl Let these propagate from the environment.
 AC_SUBST(CFLAGS) AC_SUBST(CPPFLAGS) AC_SUBST(LDFLAGS)
 
-hurd_MIG_RETCODE
-
 # See if --version-script is available.
 AC_CACHE_CHECK(for ld --version-script, hurd_cv_ld_version_script_option, [dnl
 cat > conftest.c <<\EOF
diff --git a/hurd/hurd_types.defs b/hurd/hurd_types.defs
index 63003a24..9f176fef 100644
--- a/hurd/hurd_types.defs
+++ b/hurd/hurd_types.defs
@@ -378,12 +378,7 @@ intranpayload: mach_port_t MACH_PAYLOAD_TO_PORT
 #define SCP
 #endif
 
-#ifdef HAVE_MIG_RETCODE
 #define RETURN_CODE_ARG in return_code: kern_return_t, retcode
-#else
-#define RETURN_CODE_ARG in return_code: kern_return_t
-#endif
-
 
 #ifdef USERPREFIX
 userprefix USERPREFIX;
-- 
2.39.2




[PATCH hurd] Implement device_open_new for all the translators implementing the device interface.

2023-05-07 Thread Flavio Cruz
---
 boot/Makefile |  1 +
 boot/boot.c   | 13 +
 devnode/Makefile  |  2 +-
 devnode/devnode.c | 10 ++
 eth-multiplexer/Makefile  |  2 +-
 eth-multiplexer/device_impl.c | 10 ++
 libmachdev/Makefile   |  2 +-
 libmachdev/ds_routines.c  | 10 ++
 8 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/boot/Makefile b/boot/Makefile
index e2eeb20b..bbf19ea9 100644
--- a/boot/Makefile
+++ b/boot/Makefile
@@ -26,6 +26,7 @@ MIGSTUBS = machServer.o mach_hostServer.o gnumachServer.o 
task_notifyServer.o
 OBJS = boot.o $(COMMON-OBJS) $(MIGSTUBS)
 target = boot
 MIGSFLAGS=-imacros $(srcdir)/mig-mutate.h -DHURD_DEFAULT_PAYLOAD_TO_PORT=1
+device-MIGSFLAGS=-DDEVICE_ENABLE_DEVICE_OPEN_NEW
 io-MIGSFLAGS=-DREPLY_PORTS -DHURD_DEFAULT_PAYLOAD_TO_PORT=1
 HURDLIBS = store shouldbeinlibc ihash
 LDLIBS += -lpthread
diff --git a/boot/boot.c b/boot/boot.c
index 3fa9ddab..b661f09c 100644
--- a/boot/boot.c
+++ b/boot/boot.c
@@ -991,6 +991,19 @@ ds_device_open (mach_port_t master_port,
   return device_open (master_device_port, mode, name, device);
 }
 
+kern_return_t
+ds_device_open_new (mach_port_t master_port,
+   mach_port_t reply_port,
+   mach_msg_type_name_t reply_type,
+   dev_mode_t mode,
+   const_dev_name_t name,
+   mach_port_t *device,
+   mach_msg_type_name_t *devicetype)
+{
+  return ds_device_open (master_port, reply_port, reply_type, mode,
+  name, device, devicetype);
+}
+
 kern_return_t
 ds_device_close (device_t device)
 {
diff --git a/devnode/Makefile b/devnode/Makefile
index 0964f8d4..6172ec90 100644
--- a/devnode/Makefile
+++ b/devnode/Makefile
@@ -24,7 +24,7 @@ HURDLIBS = fshelp ihash iohelp ports shouldbeinlibc trivfs
 target = devnode
 MIGSTUBS = deviceServer.o notifyServer.o
 MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h
-device-MIGSFLAGS="-DMACH_PAYLOAD_TO_PORT=ports_payload_get_name"
+device-MIGSFLAGS=-DMACH_PAYLOAD_TO_PORT=ports_payload_get_name 
-DDEVICE_ENABLE_DEVICE_OPEN_NEW
 OBJS = $(SRCS:.c=.o) $(MIGSTUBS)
 
 include ../Makeconf
diff --git a/devnode/devnode.c b/devnode/devnode.c
index bf3378ea..f5a00f1b 100644
--- a/devnode/devnode.c
+++ b/devnode/devnode.c
@@ -174,6 +174,16 @@ ds_device_open (mach_port_t master_port, mach_port_t 
reply_port,
   return err;
 }
 
+kern_return_t
+ds_device_open_new (mach_port_t master_port, mach_port_t reply_port,
+   mach_msg_type_name_t reply_portPoly,
+   dev_mode_t mode, const_dev_name_t name, mach_port_t *device,
+   mach_msg_type_name_t *devicetype)
+{
+  return ds_device_open (master_port, reply_port, reply_portPoly, mode,
+  name, device, devicetype);
+}
+
 kern_return_t
 ds_device_close (device_t device)
 {
diff --git a/eth-multiplexer/Makefile b/eth-multiplexer/Makefile
index 5f3d2739..c9dd660d 100644
--- a/eth-multiplexer/Makefile
+++ b/eth-multiplexer/Makefile
@@ -23,7 +23,7 @@ target = eth-multiplexer
 SRCS = ethernet.c vdev.c multiplexer.c dev_stat.c netfs_impl.c device_impl.c 
dead-name.c demuxer.c
 MIGSTUBS = deviceServer.o
 MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h
-device-MIGSFLAGS="-DMACH_PAYLOAD_TO_PORT=ports_payload_get_name"
+device-MIGSFLAGS=-DMACH_PAYLOAD_TO_PORT=ports_payload_get_name 
-DDEVICE_ENABLE_DEVICE_OPEN_NEW
 OBJS = $(SRCS:.c=.o) $(MIGSTUBS)
 LCLHDRS = ethernet.h util.h vdev.h netfs_impl.h
 HURDLIBS = ports ihash iohelp fshelp shouldbeinlibc netfs bpf
diff --git a/eth-multiplexer/device_impl.c b/eth-multiplexer/device_impl.c
index 152dc7bc..6a67fbd9 100644
--- a/eth-multiplexer/device_impl.c
+++ b/eth-multiplexer/device_impl.c
@@ -83,6 +83,16 @@ ds_device_open (mach_port_t master_port, mach_port_t 
reply_port,
   return D_NO_SUCH_DEVICE;
 }
 
+kern_return_t
+ds_device_open_new (mach_port_t master_port, mach_port_t reply_port,
+   mach_msg_type_name_t reply_portPoly,
+   dev_mode_t mode, const_dev_name_t name, mach_port_t *device,
+   mach_msg_type_name_t *devicetype)
+{
+  return ds_device_open (master_port, reply_port, reply_portPoly, mode,
+  name, device, devicetype);
+}
+
 kern_return_t
 ds_device_close (struct vether_device *device)
 {
diff --git a/libmachdev/Makefile b/libmachdev/Makefile
index 7b07c926..8b1396f3 100644
--- a/libmachdev/Makefile
+++ b/libmachdev/Makefile
@@ -28,7 +28,7 @@ HURDLIBS = ports trivfs
 LDLIBS += -lpthread -lmachuser
 OBJS = $(SRCS:.c=.o) $(MIGSTUBS)
 MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h
-device-MIGSFLAGS="-DMACH_PAYLOAD_TO_PORT=ports_payload_get_name"
+device-MIGSFLAGS=-DMACH_PAYLOAD_TO_PORT=ports_payload_get_name 
-DDEVICE_ENABLE_DEVICE_OPEN_NEW
 mach_i386-MIGSFLAGS="-DMACH_PAYLOAD_TO_PORT=ports_payload_get_name" \
   "-DMACH_I386_IMPORTS=import \"$(srcdir)/../libports/ports.h\";"
 
diff --git a/libmachdev/ds_routines.c b/libmachdev/ds_routines.c
index 0d60d589..6555d6e9 100644
--- a/libmachdev/ds_routines.c
+++ 

[PATCH glibc] Enable new device_open_new RPC in libmachuser.

2023-05-07 Thread Flavio Cruz
---
 mach/Makefile | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/mach/Makefile b/mach/Makefile
index a5d1252f95..2c09c29406 100644
--- a/mach/Makefile
+++ b/mach/Makefile
@@ -123,7 +123,8 @@ user-interfaces := $(filter-out 
$(mach-interface-list:%=mach/%) \
 endif
 
 # For some reason, the calls in this file are `protected' by an ifdef.
-MIGFLAGS-mach/mach4=-DMACH_PCSAMPLE
+MIGFLAGS-mach/mach4 = -DMACH_PCSAMPLE
+MIGFLAGS-device/device = -DDEVICE_ENABLE_DEVICE_OPEN_NEW
 
 # Make the MiG stubs for $(mach-shortcuts) be CALL_rpc.
 migdefines += $(foreach call,$(mach-shortcuts),-D$(call)=$(call)_rpc)
-- 
2.39.2




[PATCH glibc] Update hurd/hurdselect.c to be more portable.

2023-05-06 Thread Flavio Cruz
Summary of changes:
- Use BAD_TYPECHECK to perform type checking in a cleaner way.
  BAD_TYPECHECK is moved into sysdeps/mach/rpc.h to avoid duplication.
- Remove assertions for mach_msg_type_t since those won't work for
  x86_64.
- Update message structs to use mach_msg_type_t directly.
- Use designated initializers.
---
 hurd/hurdselect.c | 30 ++
 hurd/intr-msg.c   |  6 +-
 sysdeps/mach/hurd/ioctl.c |  6 +-
 sysdeps/mach/mach_rpc.h   | 31 +++
 4 files changed, 47 insertions(+), 26 deletions(-)
 create mode 100644 sysdeps/mach/mach_rpc.h

diff --git a/hurd/hurdselect.c b/hurd/hurdselect.c
index 08fcc92170..9630cae474 100644
--- a/hurd/hurdselect.c
+++ b/hurd/hurdselect.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -69,14 +70,6 @@ _hurd_select (int nfds,
   sigset_t oset;
   struct hurd_sigstate *ss = NULL;
 
-  union typeword   /* Use this to avoid unkosher casts.  */
-{
-  mach_msg_type_t type;
-  uint32_t word;
-};
-  assert (sizeof (union typeword) == sizeof (mach_msg_type_t));
-  assert (sizeof (uint32_t) == sizeof (mach_msg_type_t));
-
   if (nfds < 0 || (pollfds == NULL && nfds > FD_SETSIZE))
 {
   errno = EINVAL;
@@ -404,15 +397,15 @@ _hurd_select (int nfds,
  struct
{
  mach_msg_header_t head;
- union typeword err_type;
+ mach_msg_type_t err_type;
  error_t err;
} error;
  struct
{
  mach_msg_header_t head;
- union typeword err_type;
+ mach_msg_type_t err_type;
  error_t err;
- union typeword result_type;
+ mach_msg_type_t result_type;
  int result;
} success;
 #endif
@@ -443,9 +436,14 @@ _hurd_select (int nfds,
 
  /* We got a message.  Decode it.  */
 #ifdef MACH_MSG_TYPE_BIT
- const union typeword inttype =
- { type:
-   { MACH_MSG_TYPE_INTEGER_T, sizeof (integer_t) * 8, 1, 1, 0, 0 }
+ static const mach_msg_type_t inttype = {
+   .msgt_name = MACH_MSG_TYPE_INTEGER_T,
+   .msgt_size = sizeof (integer_t) * 8,
+   .msgt_number = 1,
+   .msgt_inline = TRUE,
+   .msgt_longform = FALSE,
+   .msgt_deallocate = FALSE,
+   .msgt_unused = 0
  };
 #endif
 
@@ -462,7 +460,7 @@ _hurd_select (int nfds,
  && msg.head.msgh_size >= sizeof msg.error
  && !(msg.head.msgh_bits & MACH_MSGH_BITS_COMPLEX)
 #ifdef MACH_MSG_TYPE_BIT
- && msg.error.err_type.word == inttype.word
+ && !BAD_TYPECHECK (_type, )
 #endif
  )
{
@@ -480,7 +478,7 @@ _hurd_select (int nfds,
 occurred.  */
  if (msg.error.err
 #ifdef MACH_MSG_TYPE_BIT
- || msg.success.result_type.word != inttype.word
+ || BAD_TYPECHECK (_type, )
 #endif
  || msg.head.msgh_size != sizeof msg.success)
{
diff --git a/hurd/intr-msg.c b/hurd/intr-msg.c
index b535397bfb..bc1f43d383 100644
--- a/hurd/intr-msg.c
+++ b/hurd/intr-msg.c
@@ -17,6 +17,7 @@
.  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -28,11 +29,6 @@
 # define mig_reply_header_tmig_reply_error_t
 #endif
 
-/* Macro used by MIG to cleanly check the type.  */
-#define BAD_TYPECHECK(type, check) __glibc_unlikely (({\
-  union { mach_msg_type_t t; uint32_t w; } _t, _c; \
-  _t.t = *(type); _c.t = *(check);_t.w != _c.w; }))
-
 error_t
 _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
 mach_msg_option_t option,
diff --git a/sysdeps/mach/hurd/ioctl.c b/sysdeps/mach/hurd/ioctl.c
index 66daaa751e..752cfa60f4 100644
--- a/sysdeps/mach/hurd/ioctl.c
+++ b/sysdeps/mach/hurd/ioctl.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -35,11 +36,6 @@
 #define msg_align(x) ALIGN_UP (x, __alignof__ (uintptr_t))
 #define typesize(type) (1 << (type))
 
-/* Macro used by MIG to cleanly check the type.  */
-#define BAD_TYPECHECK(type, check) __glibc_unlikely (({\
-  union { mach_msg_type_t t; uint32_t w; } _t, _c; \
-  _t.t = *(type); _c.t = *(check);_t.w != _c.w; }))
-
 /* Perform the I/O control operation specified by REQUEST on FD.
The actual type and use of ARG and the return value depend on REQUEST.  */
 int
diff --git a/sysdeps/mach/mach_rpc.h b/sysdeps/mach/mach_rpc.h
new file mode 100644
index 00..ff1ee1cae9
--- /dev/null
+++ b/sysdeps/mach/mach_rpc.h
@@ -0,0 +1,31 @@
+/* Macros for handling Mach RPC messages.
+   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
+   

[PATCH gnumach] Delete include/mach/rpc.h

2023-05-04 Thread Flavio Cruz
File is unused.
---
 Makefrag.am|  1 -
 include/mach/rpc.h | 34 --
 ipc/ipc_port.h |  1 -
 ipc/ipc_target.h   |  1 -
 ipc/mach_port.c|  1 -
 5 files changed, 38 deletions(-)
 delete mode 100644 include/mach/rpc.h

diff --git a/Makefrag.am b/Makefrag.am
index 50389ad7..5b61a1d6 100644
--- a/Makefrag.am
+++ b/Makefrag.am
@@ -403,7 +403,6 @@ include_mach_HEADERS = \
include/mach/processor_info.h \
include/mach/profil.h \
include/mach/profilparam.h \
-   include/mach/rpc.h \
include/mach/std_types.h \
include/mach/syscall_sw.h \
include/mach/task_info.h \
diff --git a/include/mach/rpc.h b/include/mach/rpc.h
deleted file mode 100644
index 36eb5921..
--- a/include/mach/rpc.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 1993,1994 The University of Utah and
- * the Computer Systems Laboratory (CSL).  All rights reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
- * IS" CONDITION.  THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
- * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * CSL requests users of this software to return to csl-d...@cs.utah.edu any
- * improvements that they make and grant CSL redistribution rights.
- */
-
-#ifndef MACH_RPC_H
-#define MACH_RPC_H
-
-#include 
-#include 
-
-/*
- * Description of a port passed up by the leaky-register RPC path
- * when it needs to perform translation.
- */
-struct rpc_port_desc {
-   mach_port_t name;
-   mach_msg_type_name_t msgt_name;
-};
-
-#endif /* MACH_RPC_H */
diff --git a/ipc/ipc_port.h b/ipc/ipc_port.h
index 022921f7..192d8806 100644
--- a/ipc/ipc_port.h
+++ b/ipc/ipc_port.h
@@ -50,7 +50,6 @@
 #include 
 #include 
 #include "ipc_target.h"
-#include 
 
 /*
  *  A receive right (port) can be in four states:
diff --git a/ipc/ipc_target.h b/ipc/ipc_target.h
index 86a0e44b..c2cc9241 100644
--- a/ipc/ipc_target.h
+++ b/ipc/ipc_target.h
@@ -27,7 +27,6 @@
 
 #include "ipc_mqueue.h"
 #include "ipc_object.h"
-#include 
 
 typedef struct ipc_target {
 
diff --git a/ipc/mach_port.c b/ipc/mach_port.c
index b35d8bcf..db6dae61 100644
--- a/ipc/mach_port.c
+++ b/ipc/mach_port.c
@@ -45,7 +45,6 @@
 #include 
 #include 
 #ifdef MIGRATING_THREADS
-#include 
 #include 
 #include 
 #endif /* MIGRATING_THREADS */
-- 
2.39.2




[PATCH hurd] Update eth-multiplexer/vdev.c to be more portable

2023-05-04 Thread Flavio Cruz
* Perform the correct alignment for x86_64.
* Use designated initializers.
---
 eth-multiplexer/vdev.c | 39 ++-
 1 file changed, 22 insertions(+), 17 deletions(-)

diff --git a/eth-multiplexer/vdev.c b/eth-multiplexer/vdev.c
index 548af9d2..f441803d 100644
--- a/eth-multiplexer/vdev.c
+++ b/eth-multiplexer/vdev.c
@@ -46,25 +46,29 @@ static int dev_num;
  * TODO every device structure should has its own lock to protect itself. */
 static pthread_mutex_t dev_list_lock = PTHREAD_MUTEX_INITIALIZER;
 
-mach_msg_type_t header_type =
+/* Should match MiG's desired_complex_alignof */
+#define MSG_ALIGNMENT __alignof__(uintptr_t)
+
+static const mach_msg_type_t header_type =
 {
-  MACH_MSG_TYPE_BYTE,
-  8,
-  NET_HDW_HDR_MAX,
-  TRUE,
-  FALSE,
-  FALSE,
-  0
+  .msgt_name = MACH_MSG_TYPE_BYTE,
+  .msgt_size = 8,
+  .msgt_number = NET_HDW_HDR_MAX,
+  .msgt_inline = TRUE,
+  .msgt_longform = FALSE,
+  .msgt_deallocate = FALSE,
+  .msgt_unused = 0
 };
 
-mach_msg_type_t packet_type =
+static const mach_msg_type_t packet_type =
 {
-  MACH_MSG_TYPE_BYTE,  /* name */
-  8,   /* size */
-  0,   /* number */
-  TRUE,/* inline */
-  FALSE,   /* longform */
-  FALSE/* deallocate */
+  .msgt_name = MACH_MSG_TYPE_BYTE,
+  .msgt_size = 8,
+  .msgt_number = 0,
+  .msgt_inline = TRUE,
+  .msgt_longform = FALSE,
+  .msgt_deallocate = FALSE,
+  .msgt_unused = 0
 };
 
 int
@@ -208,8 +212,9 @@ broadcast_pack (char *data, int datalen, struct 
vether_device *from_vdev)
 
   pack_size = datalen - sizeof (struct ethhdr);
   /* remember message sizes must be rounded up */
-  msg.msg_hdr.msgh_size = (((mach_msg_size_t) (sizeof(struct net_rcv_msg)
-  - NET_RCV_MAX + pack_size)) + 3) 
& ~3;
+  msg.msg_hdr.msgh_size = sizeof (struct net_rcv_msg) - NET_RCV_MAX + 
pack_size;
+  msg.msg_hdr.msgh_size = (mach_msg_size_t) ((msg.msg_hdr.msgh_size +
+  MSG_ALIGNMENT - 1) & ~(MSG_ALIGNMENT - 1));
 
   header = (struct ethhdr *) msg.header;
   packet = (struct packet_header *) msg.packet;
-- 
2.39.2




[PATCH glibc] Update hurd/hurdselect.c to be more portable.

2023-05-04 Thread Flavio Cruz
Summary of changes:
- Use BAD_TYPECHECK to perform type checking in a cleaner way.
  BAD_TYPECHECK is moved into sysdeps/mach/rpc.h to avoid duplication.
- Remove assertions for mach_msg_type_t since those won't work for
  x86_64.
- Update message structs to use mach_msg_type_t directly and rely on
  BAD_TYPECHECK to do the type checking.
- Use designated initializers.
---
 hurd/hurdselect.c | 34 +++---
 hurd/intr-msg.c   |  6 +-
 sysdeps/mach/hurd/ioctl.c |  6 +-
 sysdeps/mach/mach_rpc.h   | 25 +
 4 files changed, 46 insertions(+), 25 deletions(-)
 create mode 100644 sysdeps/mach/mach_rpc.h

diff --git a/hurd/hurdselect.c b/hurd/hurdselect.c
index 08fcc92170..13847ac6c0 100644
--- a/hurd/hurdselect.c
+++ b/hurd/hurdselect.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -69,13 +70,11 @@ _hurd_select (int nfds,
   sigset_t oset;
   struct hurd_sigstate *ss = NULL;
 
-  union typeword   /* Use this to avoid unkosher casts.  */
-{
-  mach_msg_type_t type;
-  uint32_t word;
-};
-  assert (sizeof (union typeword) == sizeof (mach_msg_type_t));
-  assert (sizeof (uint32_t) == sizeof (mach_msg_type_t));
+  /* TODO: add this assertion for x86_64.  */
+#ifndef __x86_64__
+  _Static_assert (sizeof (uint32_t) == sizeof (mach_msg_type_t),
+  "mach_msg_type_t needs to be the same size as uint32_t");
+#endif
 
   if (nfds < 0 || (pollfds == NULL && nfds > FD_SETSIZE))
 {
@@ -404,15 +403,15 @@ _hurd_select (int nfds,
  struct
{
  mach_msg_header_t head;
- union typeword err_type;
+ mach_msg_type_t err_type;
  error_t err;
} error;
  struct
{
  mach_msg_header_t head;
- union typeword err_type;
+ mach_msg_type_t err_type;
  error_t err;
- union typeword result_type;
+ mach_msg_type_t result_type;
  int result;
} success;
 #endif
@@ -443,9 +442,14 @@ _hurd_select (int nfds,
 
  /* We got a message.  Decode it.  */
 #ifdef MACH_MSG_TYPE_BIT
- const union typeword inttype =
- { type:
-   { MACH_MSG_TYPE_INTEGER_T, sizeof (integer_t) * 8, 1, 1, 0, 0 }
+ static const mach_msg_type_t inttype = {
+   .msgt_name = MACH_MSG_TYPE_INTEGER_T,
+   .msgt_size = sizeof (integer_t) * 8,
+   .msgt_number = 1,
+   .msgt_inline = TRUE,
+   .msgt_longform = FALSE,
+   .msgt_deallocate = FALSE,
+   .msgt_unused = 0
  };
 #endif
 
@@ -462,7 +466,7 @@ _hurd_select (int nfds,
  && msg.head.msgh_size >= sizeof msg.error
  && !(msg.head.msgh_bits & MACH_MSGH_BITS_COMPLEX)
 #ifdef MACH_MSG_TYPE_BIT
- && msg.error.err_type.word == inttype.word
+ && !BAD_TYPECHECK (_type, )
 #endif
  )
{
@@ -480,7 +484,7 @@ _hurd_select (int nfds,
 occurred.  */
  if (msg.error.err
 #ifdef MACH_MSG_TYPE_BIT
- || msg.success.result_type.word != inttype.word
+ || BAD_TYPECHECK (_type, )
 #endif
  || msg.head.msgh_size != sizeof msg.success)
{
diff --git a/hurd/intr-msg.c b/hurd/intr-msg.c
index b535397bfb..bc1f43d383 100644
--- a/hurd/intr-msg.c
+++ b/hurd/intr-msg.c
@@ -17,6 +17,7 @@
.  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -28,11 +29,6 @@
 # define mig_reply_header_tmig_reply_error_t
 #endif
 
-/* Macro used by MIG to cleanly check the type.  */
-#define BAD_TYPECHECK(type, check) __glibc_unlikely (({\
-  union { mach_msg_type_t t; uint32_t w; } _t, _c; \
-  _t.t = *(type); _c.t = *(check);_t.w != _c.w; }))
-
 error_t
 _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
 mach_msg_option_t option,
diff --git a/sysdeps/mach/hurd/ioctl.c b/sysdeps/mach/hurd/ioctl.c
index 66daaa751e..752cfa60f4 100644
--- a/sysdeps/mach/hurd/ioctl.c
+++ b/sysdeps/mach/hurd/ioctl.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -35,11 +36,6 @@
 #define msg_align(x) ALIGN_UP (x, __alignof__ (uintptr_t))
 #define typesize(type) (1 << (type))
 
-/* Macro used by MIG to cleanly check the type.  */
-#define BAD_TYPECHECK(type, check) __glibc_unlikely (({\
-  union { mach_msg_type_t t; uint32_t w; } _t, _c; \
-  _t.t = *(type); _c.t = *(check);_t.w != _c.w; }))
-
 /* Perform the I/O control operation specified by REQUEST on FD.
The actual type and use of ARG and the return value depend on REQUEST.  */
 int
diff --git a/sysdeps/mach/mach_rpc.h b/sysdeps/mach/mach_rpc.h
new file mode 100644
index 00..ec267d91e0
--- /dev/null
+++ b/sysdeps/mach/mach_rpc.h
@@ -0,0 +1,25 @@
+/* Macros for handling Mach RPC 

[PATCH gnumach] Use designated initializers in kern/ipc_kobject.c

2023-05-03 Thread Flavio Cruz
msgt_deallocate was not initialized explicitly, this fixes that too.
---
 kern/ipc_kobject.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/kern/ipc_kobject.c b/kern/ipc_kobject.c
index a0feaf40..960ef892 100644
--- a/kern/ipc_kobject.c
+++ b/kern/ipc_kobject.c
@@ -101,13 +101,14 @@ ipc_kobject_server(ipc_kmsg_t request)
 #defineInP ((mach_msg_header_t *) >ikm_header)
 #defineOutP((mig_reply_header_t *) >ikm_header)
 
-   static mach_msg_type_t RetCodeType = {
-   /* msgt_name = */   MACH_MSG_TYPE_INTEGER_32,
-   /* msgt_size = */   32,
-   /* msgt_number = */ 1,
-   /* msgt_inline = */ TRUE,
-   /* msgt_longform = */   FALSE,
-   /* msgt_unused = */ 0
+   static const mach_msg_type_t RetCodeType = {
+   .msgt_name = MACH_MSG_TYPE_INTEGER_32,
+   .msgt_size = 32,
+   .msgt_number = 1,
+   .msgt_inline = TRUE,
+   .msgt_longform = FALSE,
+   .msgt_deallocate = FALSE,
+   .msgt_unused = 0
};
OutP->Head.msgh_bits =
MACH_MSGH_BITS(MACH_MSGH_BITS_LOCAL(InP->msgh_bits), 0);
-- 
2.39.2




[PATCH gnumach] Improve portability for device/net_io.c and use designated initializers

2023-05-03 Thread Flavio Cruz
---
 device/net_io.c | 32 +---
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/device/net_io.c b/device/net_io.c
index bad6d3eb..cabb1be9 100644
--- a/device/net_io.c
+++ b/device/net_io.c
@@ -386,22 +386,23 @@ boolean_t ethernet_priority(const ipc_kmsg_t kmsg)
 }
 
 mach_msg_type_t header_type = {
-   MACH_MSG_TYPE_BYTE,
-   8,
-   NET_HDW_HDR_MAX,
-   TRUE,
-   FALSE,
-   FALSE,
-   0
+   .msgt_name = MACH_MSG_TYPE_BYTE,
+   .msgt_size = 8,
+   .msgt_number = NET_HDW_HDR_MAX,
+   .msgt_inline = TRUE,
+   .msgt_longform = FALSE,
+   .msgt_deallocate = FALSE,
+   .msgt_unused = 0
 };
 
 mach_msg_type_t packet_type = {
-   MACH_MSG_TYPE_BYTE, /* name */
-   8,  /* size */
-   0,  /* number */
-   TRUE,   /* inline */
-   FALSE,  /* longform */
-   FALSE   /* deallocate */
+   .msgt_name = MACH_MSG_TYPE_BYTE,
+   .msgt_size = 8,
+   .msgt_number = 0,
+   .msgt_inline = TRUE,
+   .msgt_longform = FALSE,
+   .msgt_deallocate = FALSE,
+   .msgt_unused = 0
 };
 
 /*
@@ -465,9 +466,10 @@ static boolean_t net_deliver(boolean_t nonblocking)
MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0);
/* remember message sizes must be rounded up */
kmsg->ikm_header.msgh_size =
-   (((mach_msg_size_t) (sizeof(struct net_rcv_msg)
+   (mach_msg_size_t) P2ROUND(sizeof(struct net_rcv_msg)
- sizeof net_kmsg(kmsg)->sent
-   - NET_RCV_MAX + count)) + 3) &~ 3;
+   - NET_RCV_MAX + count,
+   __alignof__ (uintptr_t));
kmsg->ikm_header.msgh_local_port = MACH_PORT_NULL;
kmsg->ikm_header.msgh_kind = MACH_MSGH_KIND_NORMAL;
kmsg->ikm_header.msgh_id = NET_RCV_MSG_ID;
-- 
2.39.2




[PATCH glibc] Update hurd/intr-msg.c to be more portable

2023-05-03 Thread Flavio Cruz
Summary of the changes:
- Introduce BAD_TYPECHECK from MiG to make it simpler to do type
  checking.
- Replace int type with mach_msg_type_t. This assumes that
  mach_msg_type_t is always the same size as int which is not true for
  x86_64.
- Calculate the size and align using PTR_ALIGN_UP, which is a bit
  cleaner and similar to what we do elsewhere.
- Define mach_msg_type_t to check using designated initializers.
---
 hurd/intr-msg.c | 34 +-
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/hurd/intr-msg.c b/hurd/intr-msg.c
index 716d87ab6a..a8e4d04041 100644
--- a/hurd/intr-msg.c
+++ b/hurd/intr-msg.c
@@ -28,6 +28,11 @@
 # define mig_reply_header_tmig_reply_error_t
 #endif
 
+/* Macro used by MIG to cleanly check the type.  */
+#define BAD_TYPECHECK(type, check) __glibc_unlikely (({\
+  union { mach_msg_type_t t; uint32_t w; } _t, _c; \
+  _t.t = *(type); _c.t = *(check);_t.w != _c.w; }))
+
 error_t
 _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
 mach_msg_option_t option,
@@ -61,7 +66,7 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
 #ifdef NDR_CHAR_ASCII
   NDR_record_t ndr;
 #else
-  int type;
+  mach_msg_type_t type;
 #endif
   int code;
 } check;
@@ -222,11 +227,12 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
 
  if (ty->msgtl_header.msgt_inline)
{
+ /* Calculate length of data in bytes.  */
+ const vm_size_t length = ((number * size) + 7) >> 3;
  clean_ports ((void *) ty, 0);
- /* calculate length of data in bytes, rounding up */
- ty = (void *) ty + (number * size) + 7) >> 3)
-  + sizeof (mach_msg_type_t) - 1)
- &~ (sizeof (mach_msg_type_t) - 1));
+ /* Move to the next argument.  */
+ ty = (void *) PTR_ALIGN_UP ((char *) ty + length,
+ __alignof__ (uintptr_t));
}
  else
{
@@ -354,19 +360,21 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
   {
/* We got a reply.  Was it EINTR?  */
 #ifdef MACH_MSG_TYPE_BIT
-   const union
-   {
- mach_msg_type_t t;
- int i;
-   } check =
- { t: { MACH_MSG_TYPE_INTEGER_T, sizeof (integer_t) * 8,
-1, TRUE, FALSE, FALSE, 0 } };
+   static const mach_msg_type_t type_check = {
+ .msgt_name = MACH_MSG_TYPE_INTEGER_T,
+ .msgt_size = sizeof (integer_t) * 8,
+ .msgt_number = 1,
+ .msgt_inline = TRUE,
+ .msgt_longform = FALSE,
+ .msgt_deallocate = FALSE,
+ .msgt_unused = 0
+   };
 #endif
 
 if (m->reply.RetCode == EINTR
&& m->header.msgh_size == sizeof m->reply
 #ifdef MACH_MSG_TYPE_BIT
-   && m->check.type == check.i
+   && !BAD_TYPECHECK(>check.type, _check)
 #endif
&& !(m->header.msgh_bits & MACH_MSGH_BITS_COMPLEX))
  {
-- 
2.39.2




[PATCH glibc] Update sysdeps/mach/hurd/ioctl.c to make it more portable

2023-05-03 Thread Flavio Cruz
Summary of the changes:
- Update msg_align to use ALIGN_UP like we have done in previous
  patches. Use it below whenever necessary to avoid repeating the same
  alignment logic.
- Define BAD_TYPECHECK to make it easier to do type checking in a few
  places below.
- Update io2mach_type to use designated initializers.
- Make RetCodeType use mach_msg_type_t. mach_msg_type_t is 8 byte for
  x86_64, so this make it portable.
- Also call msg_align for _IOT_COUNT2/_IOT_TYPE2 since it is more
  correct.
---
 sysdeps/mach/hurd/ioctl.c | 47 ++-
 1 file changed, 27 insertions(+), 20 deletions(-)

diff --git a/sysdeps/mach/hurd/ioctl.c b/sysdeps/mach/hurd/ioctl.c
index ab913a5943..66daaa751e 100644
--- a/sysdeps/mach/hurd/ioctl.c
+++ b/sysdeps/mach/hurd/ioctl.c
@@ -16,6 +16,7 @@
.  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -31,29 +32,40 @@
 
 #include 
 
+#define msg_align(x) ALIGN_UP (x, __alignof__ (uintptr_t))
 #define typesize(type) (1 << (type))
 
+/* Macro used by MIG to cleanly check the type.  */
+#define BAD_TYPECHECK(type, check) __glibc_unlikely (({\
+  union { mach_msg_type_t t; uint32_t w; } _t, _c; \
+  _t.t = *(type); _c.t = *(check);_t.w != _c.w; }))
 
 /* Perform the I/O control operation specified by REQUEST on FD.
The actual type and use of ARG and the return value depend on REQUEST.  */
 int
 __ioctl (int fd, unsigned long int request, ...)
 {
-#ifdef MACH_MSG_TYPE_CHAR
+#ifdef MACH_MSG_TYPE_BIT
   /* Map individual type fields to Mach IPC types.  */
   static const int mach_types[] =
 { MACH_MSG_TYPE_CHAR, MACH_MSG_TYPE_INTEGER_16, MACH_MSG_TYPE_INTEGER_32,
   MACH_MSG_TYPE_INTEGER_64 };
-#define io2mach_type(count, type) \
-  ((mach_msg_type_t) { mach_types[type], typesize (type) * 8, count, 1, 0, 0 })
+#define io2mach_type(count, type)   \
+  ((mach_msg_type_t) { \
+   .msgt_name = mach_types[type],   \
+   .msgt_size = typesize(type) * 8, \
+   .msgt_number = count,   \
+   .msgt_inline = TRUE,\
+   .msgt_longform = FALSE, \
+   .msgt_deallocate = FALSE,   \
+   .msgt_unused = 0\
+   })
 #endif
 
   /* Extract the type information encoded in the request.  */
   unsigned int type = _IOC_TYPE (request);
 
   /* Message buffer.  */
-#define msg_align(x) \
-  (((x) + sizeof (mach_msg_type_t) - 1) & ~(sizeof (mach_msg_type_t) - 1))
   struct
   {
 #ifdef MACH_MSG_TYPE_BIT
@@ -63,14 +75,14 @@ __ioctl (int fd, unsigned long int request, ...)
   struct
   {
mach_msg_header_t   Head;
-   int RetCodeType;
+   mach_msg_type_t RetCodeType;
kern_return_t   RetCode;
   } header_typecheck;
 };
 char data[3 * sizeof (mach_msg_type_t)
  + msg_align (_IOT_COUNT0 (type) * typesize (_IOT_TYPE0 (type)))
  + msg_align (_IOT_COUNT1 (type) * typesize (_IOT_TYPE1 (type)))
- + _IOT_COUNT2 (type) * typesize (_IOT_TYPE2 (type))];
+ + msg_align (_IOT_COUNT2 (type) * typesize (_IOT_TYPE2 (type)))];
 #else  /* Untyped Mach IPC format.  */
 mig_reply_error_t header;
 char data[_IOT_COUNT0 (type) * typesize (_IOT_TYPE0 (type))
@@ -128,8 +140,7 @@ __ioctl (int fd, unsigned long int request, ...)
  void *p = [1];
  *t = io2mach_type (count, type);
  p = __mempcpy (p, argptr, len);
- p = (void *) (((uintptr_t) p + sizeof (*t) - 1)
-   & ~(sizeof (*t) - 1));
+ p = (void *) msg_align ((uintptr_t) p);
  t = p;
 #else
  p = __mempcpy (p, argptr, len);
@@ -150,7 +161,7 @@ __ioctl (int fd, unsigned long int request, ...)
 #ifdef MACH_MSG_TYPE_BIT
  *t++ = io2mach_type (1, _IOTS (integer_t));
  *(integer_t *) t = (integer_t) (intptr_t) arg;
- t = (void *) t + sizeof (integer_t);
+ t = (void *) msg_align ((uintptr_t) t + sizeof (integer_t));
 #else
  *(integer_t *) p = (integer_t) (intptr_t) arg;
  p = (void *) p + sizeof (integer_t);
@@ -205,9 +216,8 @@ __ioctl (int fd, unsigned long int request, ...)
return MIG_TYPE_ERROR;
 
 #ifdef MACH_MSG_TYPE_BIT
-  if (msg.header_typecheck.RetCodeType
- != ((union { mach_msg_type_t t; int i; })
-   { t: io2mach_type (1, _IOTS (msg.header.RetCode)) }).i)
+  mach_msg_type_t ipctype = io2mach_type(1, _IOTS (msg.header.RetCode));
+  if (BAD_TYPECHECK (_typecheck.RetCodeType, ))
return MIG_TYPE_ERROR;
 #endif
   return msg.header.RetCode;
@@ -259,8 +269,7 @@ __ioctl (int fd, unsigned long int request, ...)
  /* Add the size of the type and data.  */
  reply_size += sizeof (mach_msg_type_t) + typesize (type) * count;
  /* Align it to word size.  */
- reply_size += sizeof (mach_msg_type_t) - 1;
-   

[PATCH gnumach] Use designated initializers in kern/exception.c

2023-05-03 Thread Flavio Cruz
---
 kern/exception.c | 56 
 1 file changed, 28 insertions(+), 28 deletions(-)

diff --git a/kern/exception.c b/kern/exception.c
index 10435b5c..d3fa50e1 100644
--- a/kern/exception.c
+++ b/kern/exception.c
@@ -291,33 +291,33 @@ struct mach_exception {
/* in mach/machine/vm_types.h */
 
 mach_msg_type_t exc_port_proto = {
-   /* msgt_name = */   MACH_MSG_TYPE_PORT_SEND,
-   /* msgt_size = */   PORT_T_SIZE_IN_BITS,
-   /* msgt_number = */ 1,
-   /* msgt_inline = */ TRUE,
-   /* msgt_longform = */   FALSE,
-   /* msgt_deallocate = */ FALSE,
-   /* msgt_unused = */ 0
+   .msgt_name = MACH_MSG_TYPE_PORT_SEND,
+   .msgt_size = PORT_T_SIZE_IN_BITS,
+   .msgt_number = 1,
+   .msgt_inline = TRUE,
+   .msgt_longform = FALSE,
+   .msgt_deallocate = FALSE,
+   .msgt_unused = 0
 };
 
 mach_msg_type_t exc_code_proto = {
-   /* msgt_name = */   INTEGER_T_TYPE,
-   /* msgt_size = */   INTEGER_T_SIZE_IN_BITS,
-   /* msgt_number = */ 1,
-   /* msgt_inline = */ TRUE,
-   /* msgt_longform = */   FALSE,
-   /* msgt_deallocate = */ FALSE,
-   /* msgt_unused = */ 0
+   .msgt_name = INTEGER_T_TYPE,
+   .msgt_size = INTEGER_T_SIZE_IN_BITS,
+   .msgt_number = 1,
+   .msgt_inline = TRUE,
+   .msgt_longform = FALSE,
+   .msgt_deallocate = FALSE,
+   .msgt_unused = 0
 };
 
 mach_msg_type_t exc_subcode_proto = {
-   /* msgt_name = */   RPC_LONG_INTEGER_T_TYPE,
-   /* msgt_size = */   RPC_LONG_INTEGER_T_SIZE_IN_BITS,
-   /* msgt_number = */ 1,
-   /* msgt_inline = */ TRUE,
-   /* msgt_longform = */   FALSE,
-   /* msgt_deallocate = */ FALSE,
-   /* msgt_unused = */ 0
+   .msgt_name = RPC_LONG_INTEGER_T_TYPE,
+   .msgt_size = RPC_LONG_INTEGER_T_SIZE_IN_BITS,
+   .msgt_number = 1,
+   .msgt_inline = TRUE,
+   .msgt_longform = FALSE,
+   .msgt_deallocate = FALSE,
+   .msgt_unused = 0
 };
 
 /*
@@ -780,13 +780,13 @@ exception_raise(
 
 /* Type descriptor for the return code.  */
 mach_msg_type_t exc_RetCode_proto = {
-   /* msgt_name = */   MACH_MSG_TYPE_INTEGER_32,
-   /* msgt_size = */   32,
-   /* msgt_number = */ 1,
-   /* msgt_inline = */ TRUE,
-   /* msgt_longform = */   FALSE,
-   /* msgt_deallocate = */ FALSE,
-   /* msgt_unused = */ 0
+   .msgt_name = MACH_MSG_TYPE_INTEGER_32,
+   .msgt_size = 32,
+   .msgt_number = 1,
+   .msgt_inline = TRUE,
+   .msgt_longform = FALSE,
+   .msgt_deallocate = FALSE,
+   .msgt_unused = 0
 };
 
 /*
-- 
2.39.2




[PATCH hurd] Use designated initializers when building mach_msg_type_t

2023-05-03 Thread Flavio Cruz
---
 boot/boot.c   | 16 +++
 console/display.c | 58 -
 libfshelp/start-translator-long.c | 56 -
 libpager/demuxer.c| 16 +++
 libports/manage-multithread.c | 16 +++
 libports/manage-one-thread.c  | 16 +++
 mach-defpager/default_pager.c | 16 +++
 proc/stubs.c  | 70 +++
 startup/startup.c | 14 +++
 utils/rpctrace.c  | 14 +++
 10 files changed, 146 insertions(+), 146 deletions(-)

diff --git a/boot/boot.c b/boot/boot.c
index e0c6bfb2..3fa9ddab 100644
--- a/boot/boot.c
+++ b/boot/boot.c
@@ -168,14 +168,14 @@ mig_reply_setup (
mach_msg_header_t   *out)
 {
   static const mach_msg_type_t RetCodeType = {
-   /* msgt_name = */   MACH_MSG_TYPE_INTEGER_32,
-   /* msgt_size = */   32,
-   /* msgt_number = */ 1,
-   /* msgt_inline = */ TRUE,
-   /* msgt_longform = */   FALSE,
-   /* msgt_deallocate = */ FALSE,
-   /* msgt_unused = */ 0
-   };
+.msgt_name = MACH_MSG_TYPE_INTEGER_32,
+.msgt_size = 32,
+.msgt_number = 1,
+.msgt_inline = TRUE,
+.msgt_longform = FALSE,
+.msgt_deallocate = FALSE,
+.msgt_unused = 0
+  };
 
 #defineInP (in)
 #defineOutP((mig_reply_header_t *) out)
diff --git a/console/display.c b/console/display.c
index 5c821938..071cd993 100644
--- a/console/display.c
+++ b/console/display.c
@@ -229,43 +229,43 @@ nowait_file_changed (mach_port_t notify_port, natural_t 
tickno,
   Request *InP = 
 
   static const mach_msg_type_t ticknoType = {
-/* msgt_name = */   2,
-/* msgt_size = */   32,
-/* msgt_number = */ 1,
-/* msgt_inline = */ TRUE,
-/* msgt_longform = */   FALSE,
-/* msgt_deallocate = */ FALSE,
-/* msgt_unused = */ 0
-  };  
+.msgt_name = MACH_MSG_TYPE_INTEGER_32,
+.msgt_size = 32,
+.msgt_number = 1,
+.msgt_inline = TRUE,
+.msgt_longform = FALSE,
+.msgt_deallocate = FALSE,
+.msgt_unused = 0
+  };
 
   static const mach_msg_type_t changeType = {
-/* msgt_name = */  2,
-/* msgt_size = */  32,
-/* msgt_number = */1,
-/* msgt_inline = */TRUE,
-/* msgt_longform = */  FALSE,
-/* msgt_deallocate = */FALSE,
-/* msgt_unused = */0
+.msgt_name = MACH_MSG_TYPE_INTEGER_32,
+.msgt_size = 32,
+.msgt_number = 1,
+.msgt_inline = TRUE,
+.msgt_longform = FALSE,
+.msgt_deallocate = FALSE,
+.msgt_unused = 0
   };
 
   static const mach_msg_type_t startType = {
-/* msgt_name = */  11,
-/* msgt_size = */  64,
-/* msgt_number = */1,
-/* msgt_inline = */TRUE,
-/* msgt_longform = */  FALSE,
-/* msgt_deallocate = */FALSE,
-/* msgt_unused = */0
+.msgt_name = MACH_MSG_TYPE_INTEGER_64,
+.msgt_size = 64,
+.msgt_number = 1,
+.msgt_inline = TRUE,
+.msgt_longform = FALSE,
+.msgt_deallocate = FALSE,
+.msgt_unused = 0
   };
 
   static const mach_msg_type_t endType = {
-/* msgt_name = */  11,
-/* msgt_size = */  64,
-/* msgt_number = */1,
-/* msgt_inline = */TRUE,
-/* msgt_longform = */  FALSE,
-/* msgt_deallocate = */FALSE,
-/* msgt_unused = */0
+.msgt_name = MACH_MSG_TYPE_INTEGER_64,
+.msgt_size = 64,
+.msgt_number = 1,
+.msgt_inline = TRUE,
+.msgt_longform = FALSE,
+.msgt_deallocate = FALSE,
+.msgt_unused = 0
   };
 
   InP->ticknoType = ticknoType;
diff --git a/libfshelp/start-translator-long.c 
b/libfshelp/start-translator-long.c
index 4bce337f..3541c681 100644
--- a/libfshelp/start-translator-long.c
+++ b/libfshelp/start-translator-long.c
@@ -65,43 +65,43 @@ service_fsys_startup (fshelp_open_fn_t underlying_open_fn, 
void *cookie,
   /* These should be optimized away to pure integer constants.  */
   const mach_msg_type_t flagsCheck =
 {
-  MACH_MSG_TYPE_INTEGER_32,/* msgt_name = */
-  32,  /* msgt_size = */
-  1,   /* msgt_number = */
-  TRUE,/* msgt_inline = */
-  FALSE,   /* msgt_longform = */
-  FALSE,   /* msgt_deallocate = */
-  0/* msgt_unused = */
+  .msgt_name = MACH_MSG_TYPE_INTEGER_32,
+  .msgt_size = 32,
+  .msgt_number = 1,
+  .msgt_inline = TRUE,
+  .msgt_longform = FALSE,
+  .msgt_deallocate = FALSE,
+  .msgt_unused = 0
 };
   const mach_msg_type_t control_portCheck =

[PATCH hurd] Use uintptr_t for message payloads.

2023-05-01 Thread Flavio Cruz
A follow up to 92fad38a043b75ed6b435b3efa574ede91dbe9ee in gnumach.
---
 auth/mig-decls.h|  2 +-
 eth-multiplexer/mig-decls.h |  2 +-
 exec/mig-decls.h|  2 +-
 libcons/priv.h  |  2 +-
 libdiskfs/diskfs.h  | 12 ++--
 libmachdev/mig-decls.h  |  2 +-
 libnetfs/priv.h |  4 ++--
 libpager/mig-decls.h|  2 +-
 libports/mig-decls.h|  2 +-
 libports/ports.h|  8 
 libtrivfs/mig-decls.h   |  4 ++--
 lwip/mig-decls.h|  4 ++--
 mach-defpager/mig-decls.h   |  2 +-
 pfinet/mig-decls.h  |  4 ++--
 pflocal/mig-decls.h |  4 ++--
 proc/mig-decls.h|  4 ++--
 term/mig-decls.h|  2 +-
 17 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/auth/mig-decls.h b/auth/mig-decls.h
index fa7b06d3..dab4a1fb 100644
--- a/auth/mig-decls.h
+++ b/auth/mig-decls.h
@@ -33,7 +33,7 @@ auth_port_to_handle (mach_port_t auth)
 }
 
 static inline struct authhandle * __attribute__ ((unused))
-auth_payload_to_handle (unsigned long payload)
+auth_payload_to_handle (uintptr_t payload)
 {
   return ports_lookup_payload (auth_bucket, payload, authhandle_portclass);
 }
diff --git a/eth-multiplexer/mig-decls.h b/eth-multiplexer/mig-decls.h
index 6ad9ebf9..6cb76930 100644
--- a/eth-multiplexer/mig-decls.h
+++ b/eth-multiplexer/mig-decls.h
@@ -36,7 +36,7 @@ begin_using_device_port (mach_port_t port)
 }
 
 static inline struct vether_device * __attribute__ ((unused))
-begin_using_device_payload (unsigned long payload)
+begin_using_device_payload (uintptr_t payload)
 {
   return ports_lookup_payload (port_bucket, payload, vdev_portclass);
 }
diff --git a/exec/mig-decls.h b/exec/mig-decls.h
index cf3e17da..94adfc9c 100644
--- a/exec/mig-decls.h
+++ b/exec/mig-decls.h
@@ -31,7 +31,7 @@ begin_using_bootinfo_port (mach_port_t port)
 }
 
 static inline struct bootinfo * __attribute__ ((unused))
-begin_using_bootinfo_payload (unsigned long payload)
+begin_using_bootinfo_payload (uintptr_t payload)
 {
 return ports_lookup_payload (port_bucket, payload, execboot_portclass);
 }
diff --git a/libcons/priv.h b/libcons/priv.h
index 6cdf3dbc..2fb9b26d 100644
--- a/libcons/priv.h
+++ b/libcons/priv.h
@@ -81,7 +81,7 @@ begin_using_notify_port (fs_notify_t port)
 }
 
 static inline cons_notify_t
-begin_using_notify_payload (unsigned long payload)
+begin_using_notify_payload (uintptr_t payload)
 {
   return ports_lookup_payload (cons_port_bucket, payload, cons_port_class);
 }
diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h
index be4061b4..91b868bb 100644
--- a/libdiskfs/diskfs.h
+++ b/libdiskfs/diskfs.h
@@ -889,13 +889,13 @@ void diskfs_finish_protid (struct protid *cred, struct 
iouser *user);
 
 extern struct protid * diskfs_begin_using_protid_port (file_t port);
 extern struct protid *
-diskfs_begin_using_protid_payload (unsigned long payload);
+diskfs_begin_using_protid_payload (uintptr_t payload);
 extern struct diskfs_control * diskfs_begin_using_control_port (fsys_t port);
 extern struct diskfs_control *
-diskfs_begin_using_control_port_payload (unsigned long payload);
+diskfs_begin_using_control_port_payload (uintptr_t payload);
 extern struct bootinfo *diskfs_begin_using_bootinfo_port (exec_startup_t port);
 struct bootinfo *
-diskfs_begin_using_bootinfo_payload (unsigned long payload);
+diskfs_begin_using_bootinfo_payload (uintptr_t payload);
 
 extern void diskfs_end_using_protid_port (struct protid *cred);
 extern void diskfs_end_using_control_port (struct diskfs_control *cred);
@@ -913,7 +913,7 @@ diskfs_begin_using_protid_port (file_t port)
 }
 
 DISKFS_EXTERN_INLINE struct protid *
-diskfs_begin_using_protid_payload (unsigned long payload)
+diskfs_begin_using_protid_payload (uintptr_t payload)
 {
   return ports_lookup_payload (diskfs_port_bucket,
   payload,
@@ -928,7 +928,7 @@ diskfs_begin_using_control_port (fsys_t port)
 }
 
 DISKFS_EXTERN_INLINE struct diskfs_control *
-diskfs_begin_using_control_port_payload (unsigned long payload)
+diskfs_begin_using_control_port_payload (uintptr_t payload)
 {
   return ports_lookup_payload (diskfs_port_bucket,
   payload,
@@ -943,7 +943,7 @@ diskfs_begin_using_bootinfo_port (exec_startup_t port)
 }
 
 DISKFS_EXTERN_INLINE struct bootinfo *
-diskfs_begin_using_bootinfo_payload (unsigned long payload)
+diskfs_begin_using_bootinfo_payload (uintptr_t payload)
 {
   return ports_lookup_payload (diskfs_port_bucket,
   payload,
diff --git a/libmachdev/mig-decls.h b/libmachdev/mig-decls.h
index 62eaac80..91db36b5 100644
--- a/libmachdev/mig-decls.h
+++ b/libmachdev/mig-decls.h
@@ -36,7 +36,7 @@ begin_using_device_port (mach_port_t port)
 }
 
 static inline struct mach_device * __attribute__ ((unused))
-begin_using_device_payload (unsigned long payload)
+begin_using_device_payload (uintptr_t payload)
 {
   return ports_lookup_payload (machdev_device_bucket, payload, 

[PATCH gnumach] Implement mig_deallocate to free memory when kernel server RPC succeeds

2023-05-01 Thread Flavio Cruz
In case the kernel interfaces use dynamically sized strings, we will
end up calling mig_deallocate to free the out of line string that was copied
into the kernel. As a matter of contract such type of data is freed
automatically either in kernel code when the RPC fails or in the MiG
stub if it succeeds.

This was tested by changing task_set_name to use dynamic strings and making
sure out of line data is passed when strlen(name) > 4.
---
 kern/ipc_mig.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/kern/ipc_mig.c b/kern/ipc_mig.c
index cb0b2c83..a145f8c5 100644
--- a/kern/ipc_mig.c
+++ b/kern/ipc_mig.c
@@ -303,6 +303,16 @@ mig_strncpy(char *dest, const char *src, int len)
return dest - dest_;
 }
 
+/* Called by MiG to deallocate memory, which in this case happens
+ * to be kernel memory. */
+void
+mig_deallocate(vm_address_t addr, vm_size_t size)
+{
+   (void) size;
+   /* We do the same thing as in ipc_kmsg_clean_body. */
+   vm_map_copy_discard((vm_map_copy_t) addr);
+}
+
 #definefast_send_right_lookup(name, port, abort)   
\
 MACRO_BEGIN\
ipc_space_t space = current_space();\
-- 
2.39.2




[PATCH gnumach] Use mig_support.h prototypes instead of duplicating them.

2023-05-01 Thread Flavio Cruz
* include/mach/mig_support.h: Drop the ifndef because this file is only
  used internally to compile gnumach. We export mig_support.h from glibc
  already.
* kern/ipc_mig.c: len should be vm_size_t.
* kern/ipc_mig.h: Drop duplicate prototypes.
---
 include/mach/mig_support.h | 4 +---
 kern/ipc_mig.c | 3 ++-
 kern/ipc_mig.h | 9 -
 3 files changed, 3 insertions(+), 13 deletions(-)

diff --git a/include/mach/mig_support.h b/include/mach/mig_support.h
index 0794a5fb..ed871c0f 100644
--- a/include/mach/mig_support.h
+++ b/include/mach/mig_support.h
@@ -52,8 +52,6 @@ extern mach_port_name_t   mig_get_reply_port(void);
 extern voidmig_reply_setup(const mach_msg_header_t *_request,
mach_msg_header_t *reply);
 
-#ifndef MACH_KERNEL
-extern vm_size_t   mig_strncpy(char *_dest, const char *_src, 
vm_size_t _len);
-#endif
+extern vm_size_t   mig_strncpy(char *_dest, const char *_src, vm_size_t 
_len);
 
 #endif /* not defined(_MACH_MIG_SUPPORT_H_) */
diff --git a/kern/ipc_mig.c b/kern/ipc_mig.c
index cb0b2c83..d6171877 100644
--- a/kern/ipc_mig.c
+++ b/kern/ipc_mig.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -285,7 +286,7 @@ mig_put_reply_port(
  * len - Length of destination buffer.
  */
 vm_size_t
-mig_strncpy(char *dest, const char *src, int len)
+mig_strncpy(char *dest, const char *src, vm_size_t len)
 {
char *dest_ = dest;
int i;
diff --git a/kern/ipc_mig.h b/kern/ipc_mig.h
index cd298efe..a8ee7869 100644
--- a/kern/ipc_mig.h
+++ b/kern/ipc_mig.h
@@ -139,13 +139,4 @@ io_return_t syscall_device_writev_request(
rpc_io_buf_vec_t*iovec,
rpc_vm_size_t   iocount);
 
-mach_port_name_t mig_get_reply_port(void);
-
-void mig_dealloc_reply_port(mach_port_t reply_port);
-
-void mig_put_reply_port(mach_port_t reply_port);
-
-vm_size_t
-mig_strncpy(char *dest, const char *src, int len);
-
 #endif /* _IPC_MIG_H_ */
-- 
2.39.2




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

2023-04-30 Thread Flavio Cruz
We make lib{mach,hurd}user.so only 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   |  1 +
 mach/mach/mig_support.h |  1 +
 mach/mig_strlen.c   | 26 +
 sysdeps/mach/include/mach/mig_support.h |  3 ++-
 5 files changed, 31 insertions(+), 2 deletions(-)
 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..72e9d557db 100644
--- a/mach/Versions
+++ b/mach/Versions
@@ -71,5 +71,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..c43fa953f8 100644
--- a/mach/mach/mig_support.h
+++ b/mach/mach/mig_support.h
@@ -55,5 +55,6 @@ 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 void *__mig_memcpy (void *__dst, const void *__src, vm_size_t __len);
+extern vm_size_t __mig_strlen (const char *__src);
 
 #endif /* mach/mig_support.h */
diff --git a/mach/mig_strlen.c b/mach/mig_strlen.c
new file mode 100644
index 00..3c5ef8db15
--- /dev/null
+++ b/mach/mig_strlen.c
@@ -0,0 +1,26 @@
+/* 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);
+}
diff --git a/sysdeps/mach/include/mach/mig_support.h 
b/sysdeps/mach/include/mach/mig_support.h
index 1888d481d2..242f310a9c 100644
--- a/sysdeps/mach/include/mach/mig_support.h
+++ b/sysdeps/mach/include/mach/mig_support.h
@@ -9,10 +9,11 @@ libc_hidden_proto (__mig_init)
 # include 
 
 # if defined USE_MULTIARCH && (IS_IN (libmachuser) || IS_IN (libhurduser))
-/* Avoid directly calling ifunc-enabled memcpy or strpcpy,
+/* Avoid directly calling ifunc-enabled memcpy or strlen,
because they would introduce a relocation loop between lib*user and
libc.so.  */
 #  define memcpy(dest, src, n) __mig_memcpy(dest, src, n)
+#  define strlen(src) __mig_strlen(src)
 # endif
 #endif
 
-- 
2.39.2




[PATCH mig] Add support for dynamically sized strings

2023-04-30 Thread Flavio Cruz
Dynamically sized strings can be represented as c_string[*] (*). We inline
up to 64 bytes but can pass arbitrary strings if needed out of line. Currently
implementation is limited to input arguments only (MiG will error out if
used as output).

In the user stub, we first run mig_strlen on the parameter to get
its length and pass it to msgtl_number. If the size is greater than 64,
then we pass the pointer instead, otherwise we strncpy the parameter
into the message and limit the size of the string in the final message
to only mach_msg_type_long_t + mig_strlen(string) + 1.

Tested by replacing file name for dir_lookup using c_string[*] and
bootstrapping the whole system.

(*) Today we have two other ways to use c_string:
- c_string[N]: uses a fixed size for the string and messages
always include that size if the string is smaller.
- c_string[*: N]: identical to the above as the string is limited to
length N, however, the size of the string that it occupies in the final
message is always mach_msg_type_t + strlen(string) + 1. Interestingly,
if strlen == N then the string will not be null-terminated.
---
The only difference with the previous patch is that we use mig_strlen so
that we can pick __mig_strlen when building glibc.

 parser.y   |  2 ++
 routine.c  |  3 +++
 tests/good/Makefile.am |  2 +-
 tests/good/string.defs | 36 +
 tests/includes/types.h |  5 
 tests/test_lib.sh  |  2 +-
 type.c | 48 -
 type.h | 10 +++
 user.c | 61 ++
 9 files changed, 139 insertions(+), 30 deletions(-)
 create mode 100644 tests/good/string.defs

diff --git a/parser.y b/parser.y
index ccf4726..eb7bb1a 100644
--- a/parser.y
+++ b/parser.y
@@ -609,6 +609,8 @@ CStringSpec :   syCString syLBrack IntExp 
syRBrack
|   syCString syLBrack syStar syColon
IntExp syRBrack
{ $$ = itCStringDecl($5, true); }
+   |   syCString syLBrack syStar syRBrack
+   { $$ = itIndefiniteCStringDecl(); }
;
 
 IntExp :   IntExp  syPlus  IntExp
diff --git a/routine.c b/routine.c
index 3ae9298..d5edb67 100644
--- a/routine.c
+++ b/routine.c
@@ -865,6 +865,9 @@ rtCheckRoutineArgs(routine_t *rt)
if ((it->itInName == MACH_MSG_TYPE_POLYMORPHIC) ||
(it->itOutName == MACH_MSG_TYPE_POLYMORPHIC))
rtAddPolyArg(arg);
+   if (it->itString && it->itIndefinite &&
+   akCheck(arg->argKind, akbReply))
+   error("%s: c_string[*] cannot be used as output arguments", 
arg->argName);
}
 }
 }
diff --git a/tests/good/Makefile.am b/tests/good/Makefile.am
index c5d8d7e..53a342d 100644
--- a/tests/good/Makefile.am
+++ b/tests/good/Makefile.am
@@ -17,7 +17,7 @@
 #
 
 TESTS = case.defs complex-types.defs directions.defs import.defs \
-routine.defs types.defs waittime.defs
+routine.defs string.defs types.defs waittime.defs
 EXTRA_DIST = $(TESTS) run_good_test.sh
 DEFS_LOG_COMPILER = sh ./$(srcdir)/run_good_test.sh
 
diff --git a/tests/good/string.defs b/tests/good/string.defs
new file mode 100644
index 000..4fa9654
--- /dev/null
+++ b/tests/good/string.defs
@@ -0,0 +1,36 @@
+/*
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+   This file is part of GNU MIG.
+
+   GNU MIG is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   GNU MIG 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
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GNU MIG.  If not, see .  */
+
+/* Tests the different string types.  */
+subsystem string 500;
+
+import "types.h";
+import "string.h";
+
+type fixed_string = c_string[16];
+type mach_port_t = MACH_MSG_TYPE_COPY_SEND;
+type variable_string = c_string[*: 16]
+   ctype: fixed_string;
+type dynamic_string = c_string[*];
+
+routine call(port : mach_port_t; fixed : fixed_string;
+ var: variable_string;
+ ind: dynamic_string;
+ ind2: dynamic_string;
+ out fixedret : fixed_string;
+ out varret: variable_string);
diff --git a/tests/includes/types.h b/tests/includes/types.h
index 2a70443..50d43c4 100644
--- a/tests/includes/types.h
+++ b/tests/includes/types.h
@@ -59,4 +59,9 @@ static inline int int8_to_int(int8_t n) {
   return (int) n;
 }
 
+typedef char fixed_string[16];
+typedef const char 

[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




[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




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

2023-04-27 Thread Flavio Cruz

Hi Sergey

On Wed, Apr 26, 2023 at 01:43:55PM +0300, Sergey Bugaev wrote:

Hi Flavio,

could you please explain what the difference / the advantage of
new_dev_name_t is over dev_name_t? (Preferably, put it into the commit
message too.)


tl;dr; we can get rid of mach_msg_type_long_t on x86_64.

Longer explanation: MACH_MSG_TYPE_STRING_C sets msgt_size to be 1024 and 
msgt_number to be 1. So this is the only type which overflows the 
existing msgt_size. c_string is better since it uses 
msgt_size = 8 and msgt_number is the length of the string.


Once dev_name_t and default_pager_filename_t can be represented using msgt_size 
< 255,
then we only will need a larger msgtl_size, which can be added directly in the 8 
byte mach_msg_type_t.




Isn't c_string same as MACH_MSG_TYPE_STRING_C? What are we gaining?

What is your overall plan concerning string handling in RPCs? The two
things I'd like to see improved in string handling are:

* drop static upper bounds (I already ranted about this in a
 response to one of your patches, and you said you agree...)
* avoid memcpying strings into the message body (maybe unless
 they're very short), and instead transmit them out of line / by VM
 copy; and avoid *reserving* lots of space (4096, or 128 bytes like
 here) for the string in the message body either


I sent a patch to solve this. We can probably use the new type here 
since it's strictly more flexible.




Is this a step towards any of these goals? If not, when we do figure
out the proper out-of-line dyn-sized strings, won't we have to
introduce new_new_dev_name_t and device_open_new_new_request etc?

Sorry if I'm missing something obvious here.

Sergey




[PATCH mig] Add support for dynamically sized strings

2023-04-27 Thread Flavio Cruz
Dynamically sized strings can be represented as c_string[*] (*). We inline
up to 64 bytes but can pass arbitrary strings if needed out of line. Currently
implementation is limited to input arguments only (MiG will error out if
used as output).

In the user stub, we first run strlen on the parameter to get
its length and pass it to msgtl_number. If the size is greater than 64,
then we pass the pointer instead, otherwise we strncpy the parameter
into the message and limit the size of the string in the final message
to only mach_msg_type_long_t + strlen(string) + 1.

Tested by replacing file name for dir_lookup using c_string[*] and
bootstrapping the whole system.

(*) Today we have two other ways to use c_string:
- c_string[N]: uses a fixed size for the string and messages
always include that size if the string is smaller.
- c_string[*: N]: identical to the above as the string is limited to
length N, however, the size of the string that it occupies in the final
message is always mach_msg_type_t + strlen(string) + 1. Interestingly,
if strlen == N then the string will not be null-terminated.
---
 parser.y   |  2 ++
 routine.c  |  3 +++
 tests/good/Makefile.am |  2 +-
 tests/good/string.defs | 36 +
 tests/includes/types.h |  5 
 tests/test_lib.sh  |  2 +-
 type.c | 48 -
 type.h | 10 +++
 user.c | 61 ++
 9 files changed, 139 insertions(+), 30 deletions(-)
 create mode 100644 tests/good/string.defs

diff --git a/parser.y b/parser.y
index ccf4726..eb7bb1a 100644
--- a/parser.y
+++ b/parser.y
@@ -609,6 +609,8 @@ CStringSpec :   syCString syLBrack IntExp 
syRBrack
|   syCString syLBrack syStar syColon
IntExp syRBrack
{ $$ = itCStringDecl($5, true); }
+   |   syCString syLBrack syStar syRBrack
+   { $$ = itIndefiniteCStringDecl(); }
;
 
 IntExp :   IntExp  syPlus  IntExp
diff --git a/routine.c b/routine.c
index 3ae9298..d5edb67 100644
--- a/routine.c
+++ b/routine.c
@@ -865,6 +865,9 @@ rtCheckRoutineArgs(routine_t *rt)
if ((it->itInName == MACH_MSG_TYPE_POLYMORPHIC) ||
(it->itOutName == MACH_MSG_TYPE_POLYMORPHIC))
rtAddPolyArg(arg);
+   if (it->itString && it->itIndefinite &&
+   akCheck(arg->argKind, akbReply))
+   error("%s: c_string[*] cannot be used as output arguments", 
arg->argName);
}
 }
 }
diff --git a/tests/good/Makefile.am b/tests/good/Makefile.am
index c5d8d7e..53a342d 100644
--- a/tests/good/Makefile.am
+++ b/tests/good/Makefile.am
@@ -17,7 +17,7 @@
 #
 
 TESTS = case.defs complex-types.defs directions.defs import.defs \
-routine.defs types.defs waittime.defs
+routine.defs string.defs types.defs waittime.defs
 EXTRA_DIST = $(TESTS) run_good_test.sh
 DEFS_LOG_COMPILER = sh ./$(srcdir)/run_good_test.sh
 
diff --git a/tests/good/string.defs b/tests/good/string.defs
new file mode 100644
index 000..4fa9654
--- /dev/null
+++ b/tests/good/string.defs
@@ -0,0 +1,36 @@
+/*
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+   This file is part of GNU MIG.
+
+   GNU MIG is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   GNU MIG 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
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GNU MIG.  If not, see .  */
+
+/* Tests the different string types.  */
+subsystem string 500;
+
+import "types.h";
+import "string.h";
+
+type fixed_string = c_string[16];
+type mach_port_t = MACH_MSG_TYPE_COPY_SEND;
+type variable_string = c_string[*: 16]
+   ctype: fixed_string;
+type dynamic_string = c_string[*];
+
+routine call(port : mach_port_t; fixed : fixed_string;
+ var: variable_string;
+ ind: dynamic_string;
+ ind2: dynamic_string;
+ out fixedret : fixed_string;
+ out varret: variable_string);
diff --git a/tests/includes/types.h b/tests/includes/types.h
index 2a70443..50d43c4 100644
--- a/tests/includes/types.h
+++ b/tests/includes/types.h
@@ -59,4 +59,9 @@ static inline int int8_to_int(int8_t n) {
   return (int) n;
 }
 
+typedef char fixed_string[16];
+typedef const char const_fixed_string[16];
+typedef char * dynamic_string;
+typedef const char * const_dynamic_string;
+
 #endif
diff --git a/tests/test_lib.sh 

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

2023-04-25 Thread Flavio Cruz
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 @@ routinedevice_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
+#ifKERNEL_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




Re: [PATCH] Include device/input.h in console-client

2023-04-24 Thread Flavio Cruz

Hi Samuel

On Tue, Jan 10, 2023 at 10:20:19PM +0100, Samuel Thibault wrote:

I was expecting it :)

I'll wait a bit for the updated gnumach to get uploaded etc. before
commiting it.


Is it possible to merge this patch given that a new version of gnumach 
was released recently?


Thanks



Flavio Cruz, le lun. 09 janv. 2023 22:37:47 -0500, a ecrit:

We avoid using repeated definitions and also update kd_event with the
new 64bit compatible fields (rpc_time_value).
---
 console-client/mach-inputdev.h | 56 +-
 1 file changed, 1 insertion(+), 55 deletions(-)

diff --git a/console-client/mach-inputdev.h b/console-client/mach-inputdev.h
index 985e1e1d..08119ad6 100644
--- a/console-client/mach-inputdev.h
+++ b/console-client/mach-inputdev.h
@@ -51,61 +51,7 @@
 #define _INPUTDEV_H_ 1

 #include 
-
-typedef u_short kev_type;   /* kd event type */
-
-/* (used for event records) */
-struct mouse_motion {
-  short mm_deltaX;/* units? */
-  short mm_deltaY;
-};
-typedef u_char Scancode;
-
-typedef struct {
-  kev_type type;  /* see below */
-  struct timeval time;/* timestamp */
-  union { /* value associated with event */
-boolean_t up;   /* MOUSE_LEFT .. MOUSE_RIGHT */
-Scancode sc;/* KEYBD_EVENT */
-struct mouse_motion mmotion;/* MOUSE_MOTION */
-  } value;
-} kd_event;
-#define m_deltaXmmotion.mm_deltaX
-#define m_deltaYmmotion.mm_deltaY
-
-/*
- * kd_event ID's.
- */
-#define MOUSE_LEFT  1   /* mouse left button up/down */
-#define MOUSE_MIDDLE2
-#define MOUSE_RIGHT 3
-#define MOUSE_MOTION4   /* mouse motion */
-#define KEYBD_EVENT 5   /* key up/down */
-
-
-#define IOCPARM_MASK0x1fff  /* parameter length, at most 13 bits */
-#define IOC_OUT 0x4000  /* copy out parameters */
-#define IOC_IN  0x8000U /* copy in parameters */
-
-#ifndef _IOC
-#define _IOC(inout,group,num,len) \
-(inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num))
-#endif
-#ifndef _IOR
-#define _IOR(g,n,t) _IOC(IOC_OUT,   (g), (n), sizeof(t))
-#endif
-#ifndef _IOW
-#define _IOW(g,n,t) _IOC(IOC_IN,(g), (n), sizeof(t))
-#endif
-
-#define KDSKBDMODE  _IOW('K', 1, int)   /* set keyboard mode */
-#define KB_EVENT1
-#define KB_ASCII2
-
-#define KDGKBDTYPE  _IOR('K', 2, int)   /* get keyboard type */
-#define KB_VANILLAKB0
-
-#define KDSETLEDS  _IOW('K', 5, int)/* set keyboard leds */
+#include 

 /*
  * Low 3 bits of minor are the com port #.
--
2.39.0




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




  1   2   3   4   >