[PATCH 1/7] sysv: linux: Add 64-bit time_t variant for semctl

classic Classic list List threaded Threaded
41 messages Options
123
Reply | Threaded
Open this post in threaded view
|

[PATCH 1/7] sysv: linux: Add 64-bit time_t variant for semctl

Sourceware - libc-alpha mailing list
Different than others 64-bit time_t syscalls, the SysIPC interface
does not provide a new set of syscall for y2038 safeness.  Instead it
uses ununsed fields in semid_ds structure the return the high bits for
the timestamps.

To provide a y2038 safe interface a new symbol __semctl64 is added
and __semctl is change to call it instead (it adds some extra buffer
copy for the 32 bit time_t implementation).

Two two new structures are added:

  1. kernel_semid64_ds: used internally only on 32-bit architectures
     to issue the syscall.  A handful architectures (hppa, i386, mips,
     powerpc32, sparc32) requires specific implementation due its
     specific kernel ABI.

  2. semid_ds64: this is only for __TIMESIZE != 64 to use along with
     the 64-bit semctl.  It is different than the kernel one because
     the exported 64-bit time_t might require different alignment
     depending of the architecture ABI.

So the resulting implementation does:

  1. For 64-bit architectures it assumes semid_ds already contains
     64-bit time_t fields it will result in just the __semctl symbol
     using the __semctl64 code.  The semid_ds argument is passed as-is
     to the syscall.

  2. For 32-bit architectures with default 64-bit time_t (newer ABIs
     such riscv32 or arc), it will also result in only one exported
     symbol but with the required high/low handling.

     It might be possible to optimize it further to avoid the
     kernel_semid64_ds to semun transformation if the exported ABI
     for the architectures matches the expected kernel ABI, but the
     implementation is already complex enough and don't think this
     should be a hotspot in any case.

  3. Finally for 32-bit architecture with both 32-bit and 64-bit time_t
     support we follow the already set way to provide one symbol with
     64-bit time_t support and implement the 32-bit time_t support on
     basis of the 64-bit one.

     The default 32-bit symbol will allocate and copy the semid_ds
     over multiple buffers, but this should be deprecated in favor
     of the __semctl64 anyway.

Checked on i686-linux-gnu and x86_64-linux-gnu.  I also did some sniff
tests on powerpc, powerpc64, mips, mips64, armhf, sparcv9, and
sparc64.
---
 include/sys/sem.h                             |   7 +
 .../sysv/linux/bits/types/struct_semid64_ds.h |  33 +++
 .../sysv/linux/bits/types/struct_semid_ds.h   |  21 +-
 .../linux/hppa/bits/types/struct_semid_ds.h   |   6 +-
 .../linux/hppa/struct_kernel_semid64_ds.h     |  12 +
 .../linux/i386/struct_kernel_semid64_ds.h     |  12 +
 sysdeps/unix/sysv/linux/ipc_priv.h            |  10 +
 .../linux/mips/bits/types/struct_semid_ds.h   |   4 +-
 .../linux/mips/struct_kernel_semid64_ds.h     |  10 +
 .../powerpc/bits/types/struct_semid_ds.h      |   4 +-
 .../powerpc32/struct_kernel_semid64_ds.h      |  12 +
 sysdeps/unix/sysv/linux/semctl.c              | 261 +++++++++++++++---
 .../linux/sparc/bits/types/struct_semid_ds.h  |   4 +-
 .../sparc/sparc32/struct_kernel_semid64_ds.h  |  12 +
 .../sysv/linux/struct_kernel_semid64_ds.h     |  12 +
 .../linux/x86/bits/types/struct_semid_ds.h    |   4 +-
 16 files changed, 359 insertions(+), 65 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/bits/types/struct_semid64_ds.h
 create mode 100644 sysdeps/unix/sysv/linux/hppa/struct_kernel_semid64_ds.h
 create mode 100644 sysdeps/unix/sysv/linux/i386/struct_kernel_semid64_ds.h
 create mode 100644 sysdeps/unix/sysv/linux/mips/struct_kernel_semid64_ds.h
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/struct_kernel_semid64_ds.h
 create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/struct_kernel_semid64_ds.h
 create mode 100644 sysdeps/unix/sysv/linux/struct_kernel_semid64_ds.h

diff --git a/include/sys/sem.h b/include/sys/sem.h
index 69fdf1f752..a9151e057d 100644
--- a/include/sys/sem.h
+++ b/include/sys/sem.h
@@ -5,5 +5,12 @@
 
 __typeof__ (semtimedop) __semtimedop attribute_hidden;
 
+#if __TIMESIZE == 64
+# define __semctl64 __semctl
+#else
+extern int __semctl64 (int semid, int semnum, int cmd, ...);
+libc_hidden_proto (__semctl64);
+#endif
+
 # endif
 #endif
diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_semid64_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_semid64_ds.h
new file mode 100644
index 0000000000..bda9eb4469
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/bits/types/struct_semid64_ds.h
@@ -0,0 +1,33 @@
+/* Generic implementation of the semaphore struct semid64_ds.
+   Copyright (C) 2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_SEM_H
+# error "Never include <bits/types/struct_semid_ds.h> directly; use <sys/sem.h> instead."
+#endif
+
+#if __TIMESIZE == 64
+# define __semid64_ds semid_ds
+#else
+struct __semid64_ds
+{
+  struct ipc_perm sem_perm; /* operation permission struct */
+  __time64_t sem_otime; /* last semop() time */
+  __time64_t sem_ctime; /* last time changed by semctl() */
+  __syscall_ulong_t sem_nsems; /* number of semaphores in set */
+};
+#endif
diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_semid_ds.h
index 4222e6a59f..bc26d8be08 100644
--- a/sysdeps/unix/sysv/linux/bits/types/struct_semid_ds.h
+++ b/sysdeps/unix/sysv/linux/bits/types/struct_semid_ds.h
@@ -21,26 +21,19 @@
 #endif
 
 /* Data structure describing a set of semaphores.  */
-#if __TIMESIZE == 32
 struct semid_ds
 {
   struct ipc_perm sem_perm;        /* operation permission struct */
+#if __TIMESIZE == 32
   __time_t sem_otime;              /* last semop() time */
-  __syscall_ulong_t __glibc_reserved1;
+  __syscall_ulong_t __sem_otime_high;
   __time_t sem_ctime;             /* last time changed by semctl() */
-  __syscall_ulong_t __glibc_reserved2;
-  __syscall_ulong_t sem_nsems;    /* number of semaphores in set */
-  __syscall_ulong_t __glibc_reserved3;
-  __syscall_ulong_t __glibc_reserved4;
-};
+  __syscall_ulong_t __sem_ctime_high;
 #else
-struct semid_ds
-{
-  struct ipc_perm sem_perm; /* operation permission struct */
-  __time_t sem_otime; /* last semop() time */
-  __time_t sem_ctime; /* last time changed by semctl() */
-  __syscall_ulong_t sem_nsems; /* number of semaphores in set */
+  __time_t sem_otime;
+  __time_t sem_ctime;
+#endif
+  __syscall_ulong_t sem_nsems;    /* number of semaphores in set */
   __syscall_ulong_t __glibc_reserved3;
   __syscall_ulong_t __glibc_reserved4;
 };
-#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_semid_ds.h
index d4c50b5ef8..68f9eca24c 100644
--- a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_semid_ds.h
+++ b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_semid_ds.h
@@ -21,16 +21,14 @@
 #endif
 
 /* Data structure describing a set of semaphores.  */
-#if __TIMESIZE == 32
 struct semid_ds
 {
   struct ipc_perm sem_perm;   /* operation permission struct */
-  __syscall_ulong_t __glibc_reserved1;
+  __syscall_ulong_t __sem_otime_high;
   __time_t sem_otime;         /* last semop() time */
-  __syscall_ulong_t __glibc_reserved2;
+  __syscall_ulong_t __sem_ctime_high;
   __time_t sem_ctime;         /* last time changed by semctl() */
   __syscall_ulong_t sem_nsems;    /* number of semaphores in set */
   __syscall_ulong_t __glibc_reserved3;
   __syscall_ulong_t __glibc_reserved4;
 };
-#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/struct_kernel_semid64_ds.h b/sysdeps/unix/sysv/linux/hppa/struct_kernel_semid64_ds.h
new file mode 100644
index 0000000000..2871030d0d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/struct_kernel_semid64_ds.h
@@ -0,0 +1,12 @@
+/* Analogous to kernel struct semid64_ds used on semctl.  */
+struct kernel_semid64_ds
+{
+  struct ipc_perm sem_perm;
+  unsigned long sem_otime_high;
+  unsigned long sem_otime;
+  unsigned long sem_ctime_high;
+  unsigned long sem_ctime;
+  unsigned long sem_nsems;
+  unsigned long __ununsed1;
+  unsigned long __ununsed2;
+};
diff --git a/sysdeps/unix/sysv/linux/i386/struct_kernel_semid64_ds.h b/sysdeps/unix/sysv/linux/i386/struct_kernel_semid64_ds.h
new file mode 100644
index 0000000000..bab9cf63ba
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/struct_kernel_semid64_ds.h
@@ -0,0 +1,12 @@
+/* Analogous to kernel struct semid64_ds used on semctl.  */
+struct kernel_semid64_ds
+{
+  struct ipc_perm sem_perm;
+  unsigned long sem_otime;
+  unsigned long sem_otime_high;
+  unsigned long sem_ctime;
+  unsigned long sem_ctime_high;
+  __syscall_ulong_t sem_nsems;
+  __syscall_ulong_t __unused3;
+  __syscall_ulong_t __unused4;
+};
diff --git a/sysdeps/unix/sysv/linux/ipc_priv.h b/sysdeps/unix/sysv/linux/ipc_priv.h
index 15a6e683a4..93a6e5cb24 100644
--- a/sysdeps/unix/sysv/linux/ipc_priv.h
+++ b/sysdeps/unix/sysv/linux/ipc_priv.h
@@ -53,4 +53,14 @@ struct __old_ipc_perm
 #define SEMTIMEDOP_IPC_ARGS(__nsops, __sops, __timeout) \
   (__nsops), 0, (__sops), (__timeout)
 
+/* Linux SysV ipc does not provide new syscalls for 64-bit time support on
+   32-bit architectures, but rather split the timestamps on previous unused
+   fields.  */
+#if (__WORDSIZE == 32 \
+     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
+# define __IPC_TIME64 1
+#else
+# define __IPC_TIME64 0
+#endif
+
 #include <ipc_ops.h>
diff --git a/sysdeps/unix/sysv/linux/mips/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/mips/bits/types/struct_semid_ds.h
index 8954209a29..eec4a18cae 100644
--- a/sysdeps/unix/sysv/linux/mips/bits/types/struct_semid_ds.h
+++ b/sysdeps/unix/sysv/linux/mips/bits/types/struct_semid_ds.h
@@ -27,6 +27,6 @@ struct semid_ds
   __time_t sem_otime; /* last semop() time */
   __time_t sem_ctime; /* last time changed by semctl() */
   __syscall_ulong_t sem_nsems; /* number of semaphores in set */
-  __syscall_ulong_t __glibc_reserved3;
-  __syscall_ulong_t __glibc_reserved4;
+  __syscall_ulong_t __sem_otime_high;
+  __syscall_ulong_t __sem_ctime_high;
 };
diff --git a/sysdeps/unix/sysv/linux/mips/struct_kernel_semid64_ds.h b/sysdeps/unix/sysv/linux/mips/struct_kernel_semid64_ds.h
new file mode 100644
index 0000000000..76a9d83ea5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/struct_kernel_semid64_ds.h
@@ -0,0 +1,10 @@
+/* Analogous to kernel struct semid64_ds used on semctl.  */
+struct kernel_semid64_ds
+{
+  struct ipc_perm sem_perm;
+  unsigned long sem_otime;
+  unsigned long sem_ctime;
+  unsigned long sem_nsems;
+  unsigned long sem_otime_high;
+  unsigned long sem_ctime_high;
+};
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_semid_ds.h
index 300a9b98e9..d382d93c52 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_semid_ds.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_semid_ds.h
@@ -25,9 +25,9 @@ struct semid_ds
 {
   struct ipc_perm sem_perm;   /* operation permission struct */
 #if __TIMESIZE == 32
-  __syscall_ulong_t __glibc_reserved1;
+  __syscall_ulong_t __sem_otime_high;
   __time_t sem_otime;         /* last semop() time */
-  __syscall_ulong_t __glibc_reserved2;
+  __syscall_ulong_t __sem_ctime_high;
   __time_t sem_ctime;        /* last time changed by semctl() */
 #else
   __time_t sem_otime;         /* last semop() time */
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/struct_kernel_semid64_ds.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/struct_kernel_semid64_ds.h
new file mode 100644
index 0000000000..7fa4ef6424
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/struct_kernel_semid64_ds.h
@@ -0,0 +1,12 @@
+/* Analogous to kernel struct semid64_ds used on semctl.  */
+struct kernel_semid64_ds
+{
+  struct ipc_perm sem_perm;
+  unsigned long sem_otime_high;
+  unsigned long sem_otime;
+  unsigned long sem_ctime_high;
+  unsigned long sem_ctime;
+  unsigned long sem_nsems;
+  unsigned long __unused3;
+  unsigned long __unused4;
+};
diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c
index 30571af49f..3a06270242 100644
--- a/sysdeps/unix/sysv/linux/semctl.c
+++ b/sysdeps/unix/sysv/linux/semctl.c
@@ -21,10 +21,13 @@
 #include <ipc_priv.h>
 #include <sysdep.h>
 #include <shlib-compat.h>
-#include <errno.h>
-#include <linux/posix_types.h>  /* For __kernel_mode_t.  */
+#include <bits/types/struct_semid64_ds.h>  /* For __semid64_ds.  */
+#include <linux/posix_types.h>             /* For __kernel_mode_t.  */
 
-/* Define a `union semun' suitable for Linux here.  */
+/* The struct used to issue the syscall.  For architecture that assume
+   64-bit time as default (!__ASSUME_TIME64_SYSCALLS) the syscall will
+   split the resulting 64-bit sem_{o,c}time in two fields (__sem_{o,c}time
+   and __sem_{o,c}time_hi).  */
 union semun
 {
   int val; /* value for SETVAL */
@@ -33,16 +36,89 @@ union semun
   struct seminfo *__buf; /* buffer for IPC_INFO */
 };
 
-#ifndef DEFAULT_VERSION
-# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T
-#  define DEFAULT_VERSION GLIBC_2_2
+#if __IPC_TIME64 == 0
+# define semun64 semun
+typedef union semun semctl_arg_t;
+#else
+# include <struct_kernel_semid64_ds.h>
+
+union ksemun64
+{
+  int val;
+  struct kernel_semid64_ds *buf;
+  unsigned short int *array;
+  struct seminfo *__buf;
+};
+
+# if __TIMESIZE == 64
+#  define semun64 semun
 # else
-#  define DEFAULT_VERSION GLIBC_2_31
+/* The struct used when __semctl64 is called.  */
+union semun64
+{
+  int val;
+  struct __semid64_ds *buf;
+  unsigned short int *array;
+  struct seminfo *__buf;
+};
 # endif
+
+static void
+semid64_to_ksemid64 (const struct __semid64_ds *semid64,
+     struct kernel_semid64_ds *ksemid)
+{
+  ksemid->sem_perm       = semid64->sem_perm;
+  ksemid->sem_otime      = semid64->sem_otime;
+  ksemid->sem_otime_high = semid64->sem_otime >> 32;
+  ksemid->sem_ctime      = semid64->sem_ctime;
+  ksemid->sem_ctime_high = semid64->sem_ctime >> 32;
+  ksemid->sem_nsems      = semid64->sem_nsems;
+}
+
+static void
+ksemid64_to_semid64 (const struct kernel_semid64_ds *ksemid,
+     struct __semid64_ds *semid64)
+{
+  semid64->sem_perm  = ksemid->sem_perm;
+  semid64->sem_otime = ksemid->sem_otime
+       | ((__time64_t) ksemid->sem_otime_high << 32);
+  semid64->sem_ctime = ksemid->sem_ctime
+       | ((__time64_t) ksemid->sem_ctime_high << 32);
+  semid64->sem_nsems = ksemid->sem_nsems;
+}
+
+static union ksemun64
+semun64_to_ksemun64 (int cmd, union semun64 semun64,
+     struct kernel_semid64_ds *buf)
+{
+  union ksemun64 r = { 0 };
+  switch (cmd)
+    {
+    case SETVAL:
+      r.val = semun64.val;
+      break;
+    case GETALL:
+    case SETALL:
+      r.array = semun64.array;
+      break;
+    case IPC_STAT:
+    case IPC_SET:
+      r.buf = buf;
+      semid64_to_ksemid64 (semun64.buf, r.buf);
+      break;
+    case IPC_INFO:
+    case SEM_INFO:
+      r.__buf = semun64.__buf;
+      break;
+    }
+  return r;
+}
+
+typedef union ksemun64 semctl_arg_t;
 #endif
 
 static int
-semctl_syscall (int semid, int semnum, int cmd, union semun arg)
+semctl_syscall (int semid, int semnum, int cmd, semctl_arg_t arg)
 {
 #ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
   return INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd | __IPC_64,
@@ -53,15 +129,15 @@ semctl_syscall (int semid, int semnum, int cmd, union semun arg)
 #endif
 }
 
+/* POSIX states ipc_perm mode should have type of mode_t.  */
+_Static_assert (sizeof ((struct semid_ds){0}.sem_perm.mode)
+ == sizeof (mode_t),
+ "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)");
+
 int
-__new_semctl (int semid, int semnum, int cmd, ...)
+__semctl64 (int semid, int semnum, int cmd, ...)
 {
-  /* POSIX states ipc_perm mode should have type of mode_t.  */
-  _Static_assert (sizeof ((struct semid_ds){0}.sem_perm.mode)
-  == sizeof (mode_t),
-  "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)");
-
-  union semun arg = { 0 };
+  union semun64 arg64 = { 0 };
   va_list ap;
 
   /* Get the argument only if required.  */
@@ -76,44 +152,151 @@ __new_semctl (int semid, int semnum, int cmd, ...)
     case IPC_INFO:      /* arg.__buf */
     case SEM_INFO:
       va_start (ap, cmd);
-      arg = va_arg (ap, union semun);
+      arg64 = va_arg (ap, union semun64);
       va_end (ap);
       break;
     }
 
-#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
-  struct semid_ds tmpds;
-  if (cmd == IPC_SET)
-    {
-      tmpds = *arg.buf;
-      tmpds.sem_perm.mode *= 0x10000U;
-      arg.buf = &tmpds;
-    }
+#if __IPC_TIME64
+  struct kernel_semid64_ds ksemid;
+  union ksemun64 ksemun = semun64_to_ksemun64 (cmd, arg64, &ksemid);
+  union ksemun64 arg = ksemun;
+#else
+  union semun arg = arg64;
 #endif
 
   int ret = semctl_syscall (semid, semnum, cmd, arg);
+  if (ret < 0)
+    return ret;
 
-  if (ret >= 0)
+  switch (cmd)
     {
-      switch (cmd)
- {
-        case IPC_STAT:
-        case SEM_STAT:
-        case SEM_STAT_ANY:
+    case IPC_STAT:
+    case SEM_STAT:
+    case SEM_STAT_ANY:
 #ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
-          arg.buf->sem_perm.mode >>= 16;
+      arg.buf->sem_perm.mode >>= 16;
 #else
-  /* Old Linux kernel versions might not clear the mode padding.  */
-  if (sizeof ((struct semid_ds){0}.sem_perm.mode)
-      != sizeof (__kernel_mode_t))
-    arg.buf->sem_perm.mode &= 0xFFFF;
+      /* Old Linux kernel versions might not clear the mode padding.  */
+      if (sizeof ((struct semid_ds){0}.sem_perm.mode)
+  != sizeof (__kernel_mode_t))
+ arg.buf->sem_perm.mode &= 0xFFFF;
 #endif
- }
+
+#if __IPC_TIME64
+      ksemid64_to_semid64 (arg.buf, arg64.buf);
+#endif
+    }
+
+  return ret;
+}
+#if __TIMESIZE != 64
+libc_hidden_def (__semctl64)
+
+
+/* The 64-bit time_t semid_ds version might have a different layout and
+   internal field alignment.  */
+static void
+semid64_ds_to_semid_ds (struct semid_ds *ds, const struct __semid64_ds *ds64)
+{
+  ds->sem_perm = ds64->sem_perm;
+  ds->sem_otime = ds64->sem_otime;
+  ds->sem_ctime = ds64->sem_ctime;
+  ds->sem_nsems = ds64->sem_nsems;
+}
+
+static void
+semid_ds_to_semid64_ds (struct __semid64_ds *ds64, const struct semid_ds *ds)
+{
+  ds64->sem_perm = ds->sem_perm;
+  ds64->sem_otime = ds->sem_otime
+    | ((__time64_t) ds->__sem_otime_high << 32);
+  ds64->sem_ctime = ds->sem_ctime
+    | ((__time64_t) ds->__sem_ctime_high << 32);
+  ds64->sem_nsems = ds->sem_nsems;
+}
+
+static union semun64
+semun_to_semun64 (int cmd, union semun semun, struct __semid64_ds *semid64)
+{
+  union semun64 r = { 0 };
+  switch (cmd)
+    {
+    case SETVAL:
+      r.val = semun.val;
+      break;
+    case GETALL:
+    case SETALL:
+      r.array = semun.array;
+      break;
+    case IPC_STAT:
+    case IPC_SET:
+      r.buf = semid64;
+      semid_ds_to_semid64_ds (r.buf, semun.buf);
+# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
+      if (cmd == IPC_SET)
+ r.buf->sem_perm.mode *= 0x10000U;
+# endif
+      break;
+    case IPC_INFO:
+    case SEM_INFO:
+      r.__buf = semun.__buf;
+      break;
+    }
+  return r;
+}
+
+int
+__semctl (int semid, int semnum, int cmd, ...)
+{
+  union semun arg = { 0 };
+
+  va_list ap;
+
+  /* Get the argument only if required.  */
+  switch (cmd)
+    {
+    case SETVAL:        /* arg.val */
+    case GETALL:        /* arg.array */
+    case SETALL:
+    case IPC_STAT:      /* arg.buf */
+    case IPC_SET:
+    case SEM_STAT:
+    case IPC_INFO:      /* arg.__buf */
+    case SEM_INFO:
+      va_start (ap, cmd);
+      arg = va_arg (ap, union semun);
+      va_end (ap);
+      break;
+    }
+
+  struct __semid64_ds semid64;
+  union semun64 arg64 = semun_to_semun64 (cmd, arg, &semid64);
+
+  int ret = __semctl64 (semid, semnum, cmd, arg64);
+  if (ret < 0)
+    return ret;
+
+  switch (cmd)
+    {
+    case IPC_STAT:
+    case SEM_STAT:
+    case SEM_STAT_ANY:
+      semid64_ds_to_semid_ds (arg.buf, arg64.buf);
     }
 
   return ret;
 }
-versioned_symbol (libc, __new_semctl, semctl, DEFAULT_VERSION);
+#endif
+
+#ifndef DEFAULT_VERSION
+# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T
+#  define DEFAULT_VERSION GLIBC_2_2
+# else
+#  define DEFAULT_VERSION GLIBC_2_31
+# endif
+#endif
+versioned_symbol (libc, __semctl, semctl, DEFAULT_VERSION);
 
 #if defined __ASSUME_SYSVIPC_BROKEN_MODE_T \
     && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_31)
@@ -121,7 +304,7 @@ int
 attribute_compat_text_section
 __semctl_mode16 (int semid, int semnum, int cmd, ...)
 {
-  union semun arg = { 0 };
+  semctl_arg_t arg = { 0 };
   va_list ap;
 
   /* Get the argument only if required.  */
@@ -136,7 +319,7 @@ __semctl_mode16 (int semid, int semnum, int cmd, ...)
     case IPC_INFO:      /* arg.__buf */
     case SEM_INFO:
       va_start (ap, cmd);
-      arg = va_arg (ap, union semun);
+      arg = va_arg (ap, semctl_arg_t);
       va_end (ap);
       break;
     }
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_semid_ds.h
index 46fcd79fb6..0110c1a940 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_semid_ds.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_semid_ds.h
@@ -25,9 +25,9 @@ struct semid_ds
 {
   struct ipc_perm sem_perm;   /* operation permission struct */
 #if __TIMESIZE == 32
-  __syscall_ulong_t __glibc_reserved1;
+  __syscall_ulong_t __sem_otime_high;
   __time_t sem_otime;         /* last semop() time */
-  __syscall_ulong_t __glibc_reserved2;
+  __syscall_ulong_t __sem_ctime_high;
   __time_t sem_ctime;        /* last time changed by semctl() */
 #else
   __time_t sem_otime;         /* last semop() time */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/struct_kernel_semid64_ds.h b/sysdeps/unix/sysv/linux/sparc/sparc32/struct_kernel_semid64_ds.h
new file mode 100644
index 0000000000..8c4697f9ab
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/struct_kernel_semid64_ds.h
@@ -0,0 +1,12 @@
+/* Analogous to kernel struct semid64_ds used on semctl.  */
+struct kernel_semid64_ds
+{
+  struct ipc_perm sem_perm;
+  unsigned long sem_otime_high;
+  unsigned long sem_otime;
+  unsigned long sem_ctime_high;
+  unsigned long sem_ctime;
+  unsigned long sem_nsems;
+  unsigned long __unused1;
+  unsigned long __unused2;
+};
diff --git a/sysdeps/unix/sysv/linux/struct_kernel_semid64_ds.h b/sysdeps/unix/sysv/linux/struct_kernel_semid64_ds.h
new file mode 100644
index 0000000000..f9edf0f76f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/struct_kernel_semid64_ds.h
@@ -0,0 +1,12 @@
+/* Analogous to kernel struct semid64_ds used on semctl.  */
+struct kernel_semid64_ds
+{
+  struct ipc_perm sem_perm;
+  unsigned long sem_otime;
+  unsigned long sem_otime_high;
+  unsigned long sem_ctime;
+  unsigned long sem_ctime_high;
+  unsigned long sem_nsems;
+  unsigned long __unused1;
+  unsigned long __unused2;
+};
diff --git a/sysdeps/unix/sysv/linux/x86/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/x86/bits/types/struct_semid_ds.h
index f7ec89d115..c3f2fde9fd 100644
--- a/sysdeps/unix/sysv/linux/x86/bits/types/struct_semid_ds.h
+++ b/sysdeps/unix/sysv/linux/x86/bits/types/struct_semid_ds.h
@@ -25,9 +25,9 @@ struct semid_ds
 {
   struct ipc_perm sem_perm;   /* operation permission struct */
   __time_t sem_otime;  /* last semop() time */
-  __syscall_ulong_t __glibc_reserved1;
+  __syscall_ulong_t __sem_otime_high;
   __time_t sem_ctime;  /* last time changed by semctl() */
-  __syscall_ulong_t __glibc_reserved2;
+  __syscall_ulong_t __sem_ctime_high;
   __syscall_ulong_t sem_nsems;    /* number of semaphores in set */
   __syscall_ulong_t __glibc_reserved3;
   __syscall_ulong_t __glibc_reserved4;
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 2/7] sysvipc: Split out linux struct semid_ds

Sourceware - libc-alpha mailing list
This will allow us to have architectures specify their own version.

Not semantic changes expected.  Checked with a build against the
all affected ABIs.
---
 sysdeps/unix/sysv/linux/Makefile              |  1 +
 sysdeps/unix/sysv/linux/bits/msq.h            | 39 +++-----------
 .../sysv/linux/bits/types/struct_msqid_ds.h   | 51 +++++++++++++++++++
 3 files changed, 58 insertions(+), 33 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index e02065dc8d..70e2d9e044 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -92,6 +92,7 @@ sysdep_headers += sys/mount.h sys/acct.h \
   bits/termios-c_lflag.h bits/termios-tcflow.h \
   bits/termios-misc.h \
   bits/types/struct_semid_ds.h \
+  bits/types/struct_msqid_ds.h \
   bits/ipc-perm.h
 
 tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
diff --git a/sysdeps/unix/sysv/linux/bits/msq.h b/sysdeps/unix/sysv/linux/bits/msq.h
index cc4ebae0f0..6ce6408ebc 100644
--- a/sysdeps/unix/sysv/linux/bits/msq.h
+++ b/sysdeps/unix/sysv/linux/bits/msq.h
@@ -20,7 +20,12 @@
 #endif
 
 #include <bits/types.h>
-#include <bits/msq-pad.h>
+
+/* Types used in the MSQID_DS structure definition.  */
+typedef __syscall_ulong_t msgqnum_t;
+typedef __syscall_ulong_t msglen_t;
+
+#include <bits/types/struct_msqid_ds.h>
 
 /* Define options for message queue functions.  */
 #define MSG_NOERROR 010000 /* no error if message is too big */
@@ -29,38 +34,6 @@
 # define MSG_COPY 040000 /* copy (not remove) all queue messages */
 #endif
 
-/* Types used in the structure definition.  */
-typedef __syscall_ulong_t msgqnum_t;
-typedef __syscall_ulong_t msglen_t;
-
-#if __MSQ_PAD_BEFORE_TIME
-# define __MSQ_PAD_TIME(NAME, RES) \
-  unsigned long int __glibc_reserved ## RES; __time_t NAME
-#elif __MSQ_PAD_AFTER_TIME
-# define __MSQ_PAD_TIME(NAME, RES) \
-  __time_t NAME; unsigned long int __glibc_reserved ## RES
-#else
-# define __MSQ_PAD_TIME(NAME, RES) \
-  __time_t NAME
-#endif
-
-/* Structure of record for one message inside the kernel.
-   The type `struct msg' is opaque.  */
-struct msqid_ds
-{
-  struct ipc_perm msg_perm; /* structure describing operation permission */
-  __MSQ_PAD_TIME (msg_stime, 1); /* time of last msgsnd command */
-  __MSQ_PAD_TIME (msg_rtime, 2); /* time of last msgrcv command */
-  __MSQ_PAD_TIME (msg_ctime, 3); /* time of last change */
-  __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */
-  msgqnum_t msg_qnum; /* number of messages currently on queue */
-  msglen_t msg_qbytes; /* max number of bytes allowed on queue */
-  __pid_t msg_lspid; /* pid of last msgsnd() */
-  __pid_t msg_lrpid; /* pid of last msgrcv() */
-  __syscall_ulong_t __glibc_reserved4;
-  __syscall_ulong_t __glibc_reserved5;
-};
-
 #ifdef __USE_MISC
 
 # define msg_cbytes __msg_cbytes
diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
new file mode 100644
index 0000000000..bfc56f6ac1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
@@ -0,0 +1,51 @@
+/* Generic implementation of the SysV message struct msqid_ds.
+   Copyright (C) 2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_MSG_H
+# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
+#endif
+
+#include <bits/msq-pad.h>
+
+#if __MSQ_PAD_BEFORE_TIME
+# define __MSQ_PAD_TIME(NAME, RES) \
+  unsigned long int __glibc_reserved ## RES; __time_t NAME
+#elif __MSQ_PAD_AFTER_TIME
+# define __MSQ_PAD_TIME(NAME, RES) \
+  __time_t NAME; unsigned long int __glibc_reserved ## RES
+#else
+# define __MSQ_PAD_TIME(NAME, RES) \
+  __time_t NAME
+#endif
+
+/* Structure of record for one message inside the kernel.
+   The type `struct msg' is opaque.  */
+struct msqid_ds
+{
+  struct ipc_perm msg_perm; /* structure describing operation permission */
+  __MSQ_PAD_TIME (msg_stime, 1); /* time of last msgsnd command */
+  __MSQ_PAD_TIME (msg_rtime, 2); /* time of last msgrcv command */
+  __MSQ_PAD_TIME (msg_ctime, 3); /* time of last change */
+  __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */
+  msgqnum_t msg_qnum; /* number of messages currently on queue */
+  msglen_t msg_qbytes; /* max number of bytes allowed on queue */
+  __pid_t msg_lspid; /* pid of last msgsnd() */
+  __pid_t msg_lrpid; /* pid of last msgrcv() */
+  __syscall_ulong_t __glibc_reserved4;
+  __syscall_ulong_t __glibc_reserved5;
+};
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 3/7] sysvipc: Remove the linux msq-pad.h file

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
Each architecture overrides the struct msqid_ds which its required
kernel ABI one.

Checked on x86_64-linux-gnu and some bases sysvipc tests on hppa,
mips, mipsle, mips64, mips64le, sparc64, sparcv9, powerpc64le,
powerpc64, and powerpc.
---
 sysdeps/unix/sysv/linux/Makefile              |  2 +-
 sysdeps/unix/sysv/linux/bits/msq-pad.h        | 31 ----------
 .../sysv/linux/bits/types/struct_msqid_ds.h   | 28 ++++------
 sysdeps/unix/sysv/linux/hppa/bits/msq-pad.h   | 26 ---------
 .../linux/hppa/bits/types/struct_msqid_ds.h   | 47 ++++++++++++++++
 sysdeps/unix/sysv/linux/mips/bits/msq-pad.h   | 31 ----------
 .../linux/mips/bits/types/struct_msqid_ds.h   | 56 +++++++++++++++++++
 .../unix/sysv/linux/powerpc/bits/msq-pad.h    | 26 ---------
 .../powerpc/bits/types/struct_msqid_ds.h      | 47 ++++++++++++++++
 sysdeps/unix/sysv/linux/sparc/bits/msq-pad.h  | 26 ---------
 .../linux/sparc/bits/types/struct_msqid_ds.h  | 47 ++++++++++++++++
 11 files changed, 210 insertions(+), 157 deletions(-)
 delete mode 100644 sysdeps/unix/sysv/linux/bits/msq-pad.h
 delete mode 100644 sysdeps/unix/sysv/linux/hppa/bits/msq-pad.h
 create mode 100644 sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
 delete mode 100644 sysdeps/unix/sysv/linux/mips/bits/msq-pad.h
 create mode 100644 sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
 delete mode 100644 sysdeps/unix/sysv/linux/powerpc/bits/msq-pad.h
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
 delete mode 100644 sysdeps/unix/sysv/linux/sparc/bits/msq-pad.h
 create mode 100644 sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 70e2d9e044..505087e617 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -85,7 +85,7 @@ sysdep_headers += sys/mount.h sys/acct.h \
   bits/siginfo-arch.h bits/siginfo-consts-arch.h \
   bits/procfs.h bits/procfs-id.h bits/procfs-extra.h \
   bits/procfs-prregset.h bits/mman-map-flags-generic.h \
-  bits/msq-pad.h bits/shmlba.h bits/shm-pad.h \
+  bits/shmlba.h bits/shm-pad.h \
   bits/termios-struct.h bits/termios-c_cc.h \
   bits/termios-c_iflag.h bits/termios-c_oflag.h \
   bits/termios-baud.h bits/termios-c_cflag.h \
diff --git a/sysdeps/unix/sysv/linux/bits/msq-pad.h b/sysdeps/unix/sysv/linux/bits/msq-pad.h
deleted file mode 100644
index e4ffd39f27..0000000000
--- a/sysdeps/unix/sysv/linux/bits/msq-pad.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Define where padding goes in struct msqid_ds.  Generic version.
-   Copyright (C) 2018-2020 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
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef _SYS_MSG_H
-# error "Never use <bits/msq-pad.h> directly; include <sys/msg.h> instead."
-#endif
-
-#include <bits/timesize.h>
-
-/* On most architectures, padding goes after time fields for 32-bit
-   systems and is omitted for 64-bit systems.  Some architectures pad
-   before time fields instead, or omit padding despite being
-   32-bit.  */
-
-#define __MSQ_PAD_AFTER_TIME (__TIMESIZE == 32)
-#define __MSQ_PAD_BEFORE_TIME 0
diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
index bfc56f6ac1..32173a7b60 100644
--- a/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
+++ b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
@@ -20,27 +20,23 @@
 # error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
 #endif
 
-#include <bits/msq-pad.h>
-
-#if __MSQ_PAD_BEFORE_TIME
-# define __MSQ_PAD_TIME(NAME, RES) \
-  unsigned long int __glibc_reserved ## RES; __time_t NAME
-#elif __MSQ_PAD_AFTER_TIME
-# define __MSQ_PAD_TIME(NAME, RES) \
-  __time_t NAME; unsigned long int __glibc_reserved ## RES
-#else
-# define __MSQ_PAD_TIME(NAME, RES) \
-  __time_t NAME
-#endif
-
 /* Structure of record for one message inside the kernel.
    The type `struct msg' is opaque.  */
 struct msqid_ds
 {
   struct ipc_perm msg_perm; /* structure describing operation permission */
-  __MSQ_PAD_TIME (msg_stime, 1); /* time of last msgsnd command */
-  __MSQ_PAD_TIME (msg_rtime, 2); /* time of last msgrcv command */
-  __MSQ_PAD_TIME (msg_ctime, 3); /* time of last change */
+#if __TIMESIZE == 32
+  __time_t msg_stime; /* time of last msgsnd command */
+  unsigned long int __glibc_reserved1;
+  __time_t msg_rtime; /* time of last msgsnd command */
+  unsigned long int __glibc_reserved2;
+  __time_t msg_ctime; /* time of last change */
+  unsigned long int __glibc_reserved3;
+#else
+  __time_t msg_stime; /* time of last msgsnd command */
+  __time_t msg_rtime; /* time of last msgsnd command */
+  __time_t msg_ctime; /* time of last change */
+#endif
   __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */
   msgqnum_t msg_qnum; /* number of messages currently on queue */
   msglen_t msg_qbytes; /* max number of bytes allowed on queue */
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/msq-pad.h b/sysdeps/unix/sysv/linux/hppa/bits/msq-pad.h
deleted file mode 100644
index 6986585ae7..0000000000
--- a/sysdeps/unix/sysv/linux/hppa/bits/msq-pad.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Define where padding goes in struct msqid_ds.  HPPA version.
-   Copyright (C) 2018-2020 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
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef _SYS_MSG_H
-# error "Never use <bits/msq-pad.h> directly; include <sys/msg.h> instead."
-#endif
-
-#include <bits/timesize.h>
-
-#define __MSQ_PAD_AFTER_TIME 0
-#define __MSQ_PAD_BEFORE_TIME (__TIMESIZE == 32)
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
new file mode 100644
index 0000000000..3cf70e36c4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
@@ -0,0 +1,47 @@
+/* Linux/HPPA implementation of the SysV message struct msqid_ds.
+   Copyright (C) 2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_MSG_H
+# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
+#endif
+
+/* Structure of record for one message inside the kernel.
+   The type `struct msg' is opaque.  */
+struct msqid_ds
+{
+  struct ipc_perm msg_perm; /* structure describing operation permission */
+#if __TIMESIZE == 32
+  unsigned long int __glibc_reserved1;
+  __time_t msg_stime; /* time of last msgsnd command */
+  unsigned long int __glibc_reserved2;
+  __time_t msg_rtime; /* time of last msgsnd command */
+  unsigned long int __glibc_reserved3;
+  __time_t msg_ctime; /* time of last change */
+#else
+  __time_t msg_stime; /* time of last msgsnd command */
+  __time_t msg_rtime; /* time of last msgsnd command */
+  __time_t msg_ctime; /* time of last change */
+#endif
+  __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */
+  msgqnum_t msg_qnum; /* number of messages currently on queue */
+  msglen_t msg_qbytes; /* max number of bytes allowed on queue */
+  __pid_t msg_lspid; /* pid of last msgsnd() */
+  __pid_t msg_lrpid; /* pid of last msgrcv() */
+  __syscall_ulong_t __glibc_reserved4;
+  __syscall_ulong_t __glibc_reserved5;
+};
diff --git a/sysdeps/unix/sysv/linux/mips/bits/msq-pad.h b/sysdeps/unix/sysv/linux/mips/bits/msq-pad.h
deleted file mode 100644
index 8e28c5abe1..0000000000
--- a/sysdeps/unix/sysv/linux/mips/bits/msq-pad.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Define where padding goes in struct msqid_ds.  MIPS version.
-   Copyright (C) 2018-2020 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
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef _SYS_MSG_H
-# error "Never use <bits/msq-pad.h> directly; include <sys/msg.h> instead."
-#endif
-
-#include <bits/timesize.h>
-
-#ifdef __MIPSEL__
-# define __MSQ_PAD_AFTER_TIME (__TIMESIZE == 32)
-# define __MSQ_PAD_BEFORE_TIME 0
-#else
-# define __MSQ_PAD_AFTER_TIME 0
-# define __MSQ_PAD_BEFORE_TIME (__TIMESIZE == 32)
-#endif
diff --git a/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
new file mode 100644
index 0000000000..85fdeef274
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
@@ -0,0 +1,56 @@
+/* Linux/PowerPC implementation of the SysV message struct msqid_ds.
+   Copyright (C) 2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_MSG_H
+# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
+#endif
+
+/* Structure of record for one message inside the kernel.
+   The type `struct msg' is opaque.  */
+struct msqid_ds
+{
+  struct ipc_perm msg_perm; /* structure describing operation permission */
+#if __TIMESIZE == 32
+# ifdef __MIPSEL__
+  __time_t msg_stime; /* time of last msgsnd command */
+  unsigned long int __glibc_reserved1;
+  __time_t msg_rtime; /* time of last msgsnd command */
+  unsigned long int __glibc_reserved2;
+  __time_t msg_ctime; /* time of last change */
+  unsigned long int __glibc_reserved3;
+# else
+  unsigned long int __glibc_reserved1;
+  __time_t msg_stime; /* time of last msgsnd command */
+  unsigned long int __glibc_reserved2;
+  __time_t msg_rtime; /* time of last msgsnd command */
+  unsigned long int __glibc_reserved3;
+  __time_t msg_ctime; /* time of last change */
+# endif
+#else
+  __time_t msg_stime; /* time of last msgsnd command */
+  __time_t msg_rtime; /* time of last msgsnd command */
+  __time_t msg_ctime; /* time of last change */
+#endif
+  __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */
+  msgqnum_t msg_qnum; /* number of messages currently on queue */
+  msglen_t msg_qbytes; /* max number of bytes allowed on queue */
+  __pid_t msg_lspid; /* pid of last msgsnd() */
+  __pid_t msg_lrpid; /* pid of last msgrcv() */
+  __syscall_ulong_t __glibc_reserved4;
+  __syscall_ulong_t __glibc_reserved5;
+};
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/msq-pad.h b/sysdeps/unix/sysv/linux/powerpc/bits/msq-pad.h
deleted file mode 100644
index e2b9310800..0000000000
--- a/sysdeps/unix/sysv/linux/powerpc/bits/msq-pad.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Define where padding goes in struct msqid_ds.  PowerPC version.
-   Copyright (C) 2018-2020 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
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef _SYS_MSG_H
-# error "Never use <bits/msq-pad.h> directly; include <sys/msg.h> instead."
-#endif
-
-#include <bits/timesize.h>
-
-#define __MSQ_PAD_AFTER_TIME 0
-#define __MSQ_PAD_BEFORE_TIME (__TIMESIZE == 32)
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
new file mode 100644
index 0000000000..4ae2fbcbdc
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
@@ -0,0 +1,47 @@
+/* Linux/PowerPC implementation of the SysV message struct msqid_ds.
+   Copyright (C) 2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_MSG_H
+# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
+#endif
+
+/* Structure of record for one message inside the kernel.
+   The type `struct msg' is opaque.  */
+struct msqid_ds
+{
+  struct ipc_perm msg_perm; /* structure describing operation permission */
+#if __TIMESIZE == 32
+  unsigned long int __glibc_reserved1;
+  __time_t msg_stime; /* time of last msgsnd command */
+  unsigned long int __glibc_reserved2;
+  __time_t msg_rtime; /* time of last msgsnd command */
+  unsigned long int __glibc_reserved3;
+  __time_t msg_ctime; /* time of last change */
+#else
+  __time_t msg_stime; /* time of last msgsnd command */
+  __time_t msg_rtime; /* time of last msgsnd command */
+  __time_t msg_ctime; /* time of last change */
+#endif
+  __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */
+  msgqnum_t msg_qnum; /* number of messages currently on queue */
+  msglen_t msg_qbytes; /* max number of bytes allowed on queue */
+  __pid_t msg_lspid; /* pid of last msgsnd() */
+  __pid_t msg_lrpid; /* pid of last msgrcv() */
+  __syscall_ulong_t __glibc_reserved4;
+  __syscall_ulong_t __glibc_reserved5;
+};
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/msq-pad.h b/sysdeps/unix/sysv/linux/sparc/bits/msq-pad.h
deleted file mode 100644
index 99fdf8c8f0..0000000000
--- a/sysdeps/unix/sysv/linux/sparc/bits/msq-pad.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Define where padding goes in struct msqid_ds.  SPARC version.
-   Copyright (C) 2018-2020 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
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef _SYS_MSG_H
-# error "Never use <bits/msq-pad.h> directly; include <sys/msg.h> instead."
-#endif
-
-#include <bits/timesize.h>
-
-#define __MSQ_PAD_AFTER_TIME 0
-#define __MSQ_PAD_BEFORE_TIME (__TIMESIZE == 32)
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h
new file mode 100644
index 0000000000..71980839c7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h
@@ -0,0 +1,47 @@
+/* Linux/SPARC implementation of the SysV message struct msqid_ds.
+   Copyright (C) 2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_MSG_H
+# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
+#endif
+
+/* Structure of record for one message inside the kernel.
+   The type `struct msg' is opaque.  */
+struct msqid_ds
+{
+  struct ipc_perm msg_perm; /* structure describing operation permission */
+#if __TIMESIZE == 32
+  unsigned long int __glibc_reserved1;
+  __time_t msg_stime; /* time of last msgsnd command */
+  unsigned long int __glibc_reserved2;
+  __time_t msg_rtime; /* time of last msgsnd command */
+  unsigned long int __glibc_reserved3;
+  __time_t msg_ctime; /* time of last change */
+#else
+  __time_t msg_stime; /* time of last msgsnd command */
+  __time_t msg_rtime; /* time of last msgsnd command */
+  __time_t msg_ctime; /* time of last change */
+#endif
+  __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */
+  msgqnum_t msg_qnum; /* number of messages currently on queue */
+  msglen_t msg_qbytes; /* max number of bytes allowed on queue */
+  __pid_t msg_lspid; /* pid of last msgsnd() */
+  __pid_t msg_lrpid; /* pid of last msgrcv() */
+  __syscall_ulong_t __glibc_reserved4;
+  __syscall_ulong_t __glibc_reserved5;
+};
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 4/7] sysv: linux: Add 64-bit time_t variant for msgctl

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
To provide a y2038 safe interface a new symbol __msgctl64 is added
and __msgctl is change to call it instead (it adds some extra buffer
copy for the 32 bit time_t implementation).

Two two new structures are added:

  1. kernel_msqid64_ds: used internally only on 32-bit architectures
     to issue the syscall.  A handful architectures (hppa, i386, mips,
     powerpc32, and sparc32) requires specific implementation due its
     specific kernel ABI.

  2. msqid_ds64: this is only for __TIMESIZE != 64 to use along with
     the 64-bit semctl.  It is different than the kernel one because
     the exported 64-bit time_t might require different alignment
     depending of the architecture ABI.

So the resulting implementation does:

  1. For 64-bit architectures it assumes msqid_ds already contains
     64-bit time_t fields it will result in just the __msgctl symbol
     using the __msgctl64 code.  The msgid_ds argument is passed as-is
     to the syscall.

  2. For 32-bit architectures with default 64-bit time_t (newer ABIs
     such riscv32 or arc), it will also result in only one exported
     symbol but with the required high/low time handling.

  3. Finally for 32-bit architecture with both 32-bit and 64-bit time_t
     support we follow the already set way to provide one symbol with
     64-bit time_t support and implement the 32-bit time_t support on
     basis of the 64-bit one.

     The default 32-bit symbol will allocate and copy the msqid_ds
     over multiple buffers, but this should be deprecated in favor
     of the __msgctl64 anyway.

Checked on i686-linux-gnu and x86_64-linux-gnu.  I also did some sniff
tests on powerpc, powerpc64, mips, mips64, armhf, sparcv9, and
sparc64.
---
 include/sys/msg.h                             |  10 +
 .../sysv/linux/bits/types/struct_msqid64_ds.h |  38 ++++
 .../sysv/linux/bits/types/struct_msqid_ds.h   |   6 +-
 .../linux/hppa/bits/types/struct_msqid_ds.h   |   6 +-
 .../linux/hppa/struct_kernel_msqid64_ds.h     |  18 ++
 .../linux/i386/struct_kernel_msqid64_ds.h     |  18 ++
 .../linux/mips/bits/types/struct_msqid_ds.h   |  12 +-
 .../linux/mips/struct_kernel_msqid64_ds.h     |  33 ++++
 sysdeps/unix/sysv/linux/msgctl.c              | 179 ++++++++++++++----
 .../powerpc/bits/types/struct_msqid_ds.h      |   6 +-
 .../powerpc32/struct_kernel_msqid64_ds.h      |  18 ++
 sysdeps/unix/sysv/linux/semctl.c              |  27 +--
 .../linux/sparc/bits/types/struct_msqid_ds.h  |   6 +-
 .../sparc/sparc32/struct_kernel_msqid64_ds.h  |  18 ++
 .../sysv/linux/struct_kernel_msqid64_ds.h     |  19 ++
 15 files changed, 350 insertions(+), 64 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/bits/types/struct_msqid64_ds.h
 create mode 100644 sysdeps/unix/sysv/linux/hppa/struct_kernel_msqid64_ds.h
 create mode 100644 sysdeps/unix/sysv/linux/i386/struct_kernel_msqid64_ds.h
 create mode 100644 sysdeps/unix/sysv/linux/mips/struct_kernel_msqid64_ds.h
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/struct_kernel_msqid64_ds.h
 create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/struct_kernel_msqid64_ds.h
 create mode 100644 sysdeps/unix/sysv/linux/struct_kernel_msqid64_ds.h

diff --git a/include/sys/msg.h b/include/sys/msg.h
index 43ec5b9472..522903f818 100644
--- a/include/sys/msg.h
+++ b/include/sys/msg.h
@@ -6,6 +6,16 @@ extern ssize_t __libc_msgrcv (int msqid, void *msgp, size_t msgsz,
       long int msgtyp, int msgflg);
 extern int __libc_msgsnd (int msqid, const void *msgp, size_t msgsz,
   int msgflg);
+
+# include <bits/types/struct_msqid64_ds.h>
+
+# if __TIMESIZE == 64
+#  define __msgctl64 __msgctl
+# else
+extern int __msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf);
+libc_hidden_proto (__msgctl64);
+# endif
+
 #endif
 
 #endif
diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_msqid64_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_msqid64_ds.h
new file mode 100644
index 0000000000..3536c8ea62
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/bits/types/struct_msqid64_ds.h
@@ -0,0 +1,38 @@
+/* Generic implementation of the SysV message struct msqid64_ds.
+   Copyright (C) 2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_MSG_H
+# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
+#endif
+
+#if __TIMESIZE == 64
+# define __msqid64_ds msqid_ds
+#else
+struct __msqid64_ds
+{
+  struct ipc_perm msg_perm; /* structure describing operation permission */
+  __time64_t msg_stime; /* time of last msgsnd command */
+  __time64_t msg_rtime; /* time of last msgsnd command */
+  __time64_t msg_ctime; /* time of last change */
+  __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */
+  msgqnum_t msg_qnum; /* number of messages currently on queue */
+  msglen_t msg_qbytes; /* max number of bytes allowed on queue */
+  __pid_t msg_lspid; /* pid of last msgsnd() */
+  __pid_t msg_lrpid; /* pid of last msgrcv() */
+};
+#endif
diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
index 32173a7b60..43b38175ad 100644
--- a/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
+++ b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
@@ -27,11 +27,11 @@ struct msqid_ds
   struct ipc_perm msg_perm; /* structure describing operation permission */
 #if __TIMESIZE == 32
   __time_t msg_stime; /* time of last msgsnd command */
-  unsigned long int __glibc_reserved1;
+  unsigned long int __msg_stime_high;
   __time_t msg_rtime; /* time of last msgsnd command */
-  unsigned long int __glibc_reserved2;
+  unsigned long int __msg_rtime_high;
   __time_t msg_ctime; /* time of last change */
-  unsigned long int __glibc_reserved3;
+  unsigned long int __msg_ctime_high;
 #else
   __time_t msg_stime; /* time of last msgsnd command */
   __time_t msg_rtime; /* time of last msgsnd command */
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
index 3cf70e36c4..16eac46941 100644
--- a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
+++ b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
@@ -26,11 +26,11 @@ struct msqid_ds
 {
   struct ipc_perm msg_perm; /* structure describing operation permission */
 #if __TIMESIZE == 32
-  unsigned long int __glibc_reserved1;
+  unsigned long int __msg_stime_high;
   __time_t msg_stime; /* time of last msgsnd command */
-  unsigned long int __glibc_reserved2;
+  unsigned long int __msg_rtime_high;
   __time_t msg_rtime; /* time of last msgsnd command */
-  unsigned long int __glibc_reserved3;
+  unsigned long int __msg_ctime_high;
   __time_t msg_ctime; /* time of last change */
 #else
   __time_t msg_stime; /* time of last msgsnd command */
diff --git a/sysdeps/unix/sysv/linux/hppa/struct_kernel_msqid64_ds.h b/sysdeps/unix/sysv/linux/hppa/struct_kernel_msqid64_ds.h
new file mode 100644
index 0000000000..69a63ee27a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/struct_kernel_msqid64_ds.h
@@ -0,0 +1,18 @@
+/* Analogous to kernel struct msqid64_ds used on msgctl.  */
+struct kernel_msqid64_ds
+{
+  struct ipc_perm msg_perm;
+  unsigned long msg_stime_high;
+  unsigned long msg_stime;
+  unsigned long msg_rtime_high;
+  unsigned long msg_rtime;
+  unsigned long msg_ctime_high;
+  unsigned long msg_ctime;
+  unsigned long msg_cbytes;
+  unsigned long msg_qnum;
+  unsigned long msg_qbytes;
+  __pid_t msg_lspid;
+  __pid_t msg_lrpid;
+  unsigned long __unused1;
+  unsigned long __unused2;
+};
diff --git a/sysdeps/unix/sysv/linux/i386/struct_kernel_msqid64_ds.h b/sysdeps/unix/sysv/linux/i386/struct_kernel_msqid64_ds.h
new file mode 100644
index 0000000000..65b940567b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/struct_kernel_msqid64_ds.h
@@ -0,0 +1,18 @@
+/* Analogous to kernel struct compat_msqid64_ds used on msgctl.  */
+struct kernel_msqid64_ds
+{
+  struct ipc_perm msg_perm;
+  unsigned long msg_stime;
+  unsigned long msg_stime_high;
+  unsigned long msg_rtime;
+  unsigned long msg_rtime_high;
+  unsigned long msg_ctime;
+  unsigned long msg_ctime_high;
+  unsigned long msg_cbytes;
+  unsigned long msg_qnum;
+  unsigned long msg_qbytes;
+  __pid_t msg_lspid;
+  __pid_t msg_lrpid;
+  unsigned long __unused1;
+  unsigned long __unused2;
+};
diff --git a/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
index 85fdeef274..9ff010c763 100644
--- a/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
+++ b/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
@@ -28,17 +28,17 @@ struct msqid_ds
 #if __TIMESIZE == 32
 # ifdef __MIPSEL__
   __time_t msg_stime; /* time of last msgsnd command */
-  unsigned long int __glibc_reserved1;
+  unsigned long int __msg_stime_high;
   __time_t msg_rtime; /* time of last msgsnd command */
-  unsigned long int __glibc_reserved2;
+  unsigned long int __msg_rtime_high;
   __time_t msg_ctime; /* time of last change */
-  unsigned long int __glibc_reserved3;
+  unsigned long int __msg_ctime_high;
 # else
-  unsigned long int __glibc_reserved1;
+  unsigned long int __msg_stime_high;
   __time_t msg_stime; /* time of last msgsnd command */
-  unsigned long int __glibc_reserved2;
+  unsigned long int __msg_rtime_high;
   __time_t msg_rtime; /* time of last msgsnd command */
-  unsigned long int __glibc_reserved3;
+  unsigned long int __msg_ctime_high;
   __time_t msg_ctime; /* time of last change */
 # endif
 #else
diff --git a/sysdeps/unix/sysv/linux/mips/struct_kernel_msqid64_ds.h b/sysdeps/unix/sysv/linux/mips/struct_kernel_msqid64_ds.h
new file mode 100644
index 0000000000..9cfd5a0dfe
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/struct_kernel_msqid64_ds.h
@@ -0,0 +1,33 @@
+/* Analogous to kernel struct msqid64_ds used on msgctl.  */
+struct kernel_msqid64_ds
+{
+  struct ipc_perm msg_perm;
+#if __TIMESIZE == 32
+# ifdef __MIPSEL__
+  unsigned long int msg_stime;
+  unsigned long int msg_stime_high;
+  unsigned long int msg_rtime;
+  unsigned long int msg_rtime_high;
+  unsigned long int msg_ctime;
+  unsigned long int msg_ctime_high;
+# else
+  unsigned long int msg_stime_high;
+  unsigned long int msg_stime;
+  unsigned long int msg_rtime_high;
+  unsigned long int msg_rtime;
+  unsigned long int msg_ctime_high;
+  unsigned long int msg_ctime;
+# endif
+#else
+  unsigned long int msg_stime;
+  unsigned long int msg_rtime;
+  unsigned long int msg_ctime;
+#endif
+  unsigned long int msg_cbytes;
+  unsigned long int msg_qnum;
+  unsigned long int msg_qbytes;
+  __pid_t msg_lspid;
+  __pid_t msg_lrpid;
+  unsigned long int __unused1;
+  unsigned long int __unused2;
+};
diff --git a/sysdeps/unix/sysv/linux/msgctl.c b/sysdeps/unix/sysv/linux/msgctl.c
index fd46aec1a0..a7f7651280 100644
--- a/sysdeps/unix/sysv/linux/msgctl.c
+++ b/sysdeps/unix/sysv/linux/msgctl.c
@@ -23,16 +23,55 @@
 #include <errno.h>
 #include <linux/posix_types.h>  /* For __kernel_mode_t.  */
 
-#ifndef DEFAULT_VERSION
-# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T
-#  define DEFAULT_VERSION GLIBC_2_2
-# else
-#  define DEFAULT_VERSION GLIBC_2_31
-# endif
+/* POSIX states ipc_perm mode should have type of mode_t.  */
+_Static_assert (sizeof ((struct msqid_ds){0}.msg_perm.mode)
+ == sizeof (mode_t),
+ "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)");
+
+#if __IPC_TIME64 == 0
+typedef struct msqid_ds msgctl_arg_t;
+#else
+# include <struct_kernel_msqid64_ds.h>
+
+static void
+msqid64_to_kmsqid64 (const struct __msqid64_ds *msqid64,
+     struct kernel_msqid64_ds *kmsqid)
+{
+  kmsqid->msg_perm       = msqid64->msg_perm;
+  kmsqid->msg_stime      = msqid64->msg_stime;
+  kmsqid->msg_stime_high = msqid64->msg_stime >> 32;
+  kmsqid->msg_rtime      = msqid64->msg_rtime;
+  kmsqid->msg_rtime_high = msqid64->msg_rtime >> 32;
+  kmsqid->msg_ctime      = msqid64->msg_ctime;
+  kmsqid->msg_ctime_high = msqid64->msg_ctime >> 32;
+  kmsqid->msg_qnum       = msqid64->msg_qnum;
+  kmsqid->msg_qbytes     = msqid64->msg_qbytes;
+  kmsqid->msg_lspid      = msqid64->msg_lspid;
+  kmsqid->msg_lrpid      = msqid64->msg_lrpid;
+}
+
+static void
+kmsqid64_to_msqid64 (const struct kernel_msqid64_ds *kmsqid,
+     struct __msqid64_ds *msqid64)
+{
+  msqid64->msg_perm   = kmsqid->msg_perm;
+  msqid64->msg_stime  = kmsqid->msg_stime
+        | ((__time64_t) kmsqid->msg_stime_high << 32);
+  msqid64->msg_rtime  = kmsqid->msg_rtime
+        | ((__time64_t) kmsqid->msg_rtime_high << 32);
+  msqid64->msg_ctime  = kmsqid->msg_ctime
+        | ((__time64_t) kmsqid->msg_ctime_high << 32);
+  msqid64->msg_qnum   = kmsqid->msg_qnum;
+  msqid64->msg_qbytes = kmsqid->msg_qbytes;
+  msqid64->msg_lspid  = kmsqid->msg_lspid;
+  msqid64->msg_lrpid  = kmsqid->msg_lrpid;
+}
+
+typedef struct kernel_msqid64_ds msgctl_arg_t;
 #endif
 
 static int
-msgctl_syscall (int msqid, int cmd, struct msqid_ds *buf)
+msgctl_syscall (int msqid, int cmd, msgctl_arg_t *buf)
 {
 #ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
   return INLINE_SYSCALL_CALL (msgctl, msqid, cmd | __IPC_64, buf);
@@ -43,46 +82,118 @@ msgctl_syscall (int msqid, int cmd, struct msqid_ds *buf)
 }
 
 int
-__new_msgctl (int msqid, int cmd, struct msqid_ds *buf)
+__msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf)
 {
-  /* POSIX states ipc_perm mode should have type of mode_t.  */
-  _Static_assert (sizeof ((struct msqid_ds){0}.msg_perm.mode)
-  == sizeof (mode_t),
-  "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)");
-
-#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
-  struct msqid_ds tmpds;
-  if (cmd == IPC_SET)
+#if __IPC_TIME64
+  struct kernel_msqid64_ds ksemid, *arg = NULL;
+  if (buf != NULL)
     {
-      tmpds = *buf;
-      tmpds.msg_perm.mode *= 0x10000U;
-      buf = &tmpds;
+      msqid64_to_kmsqid64 (buf, &ksemid);
+      arg = &ksemid;
     }
+# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
+  if (cmd == IPC_SET)
+    arg->msg_perm.mode *= 0x10000U;
+# endif
+#else
+  msgctl_arg_t *arg = buf;
 #endif
 
-  int ret = msgctl_syscall (msqid, cmd, buf);
+  int ret = msgctl_syscall (msqid, cmd, arg);
+  if (ret < 0)
+    return ret;
 
-  if (ret >= 0)
+  switch (cmd)
     {
-      switch (cmd)
- {
- case IPC_STAT:
- case MSG_STAT:
- case MSG_STAT_ANY:
+    case IPC_STAT:
+    case MSG_STAT:
+    case MSG_STAT_ANY:
 #ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
-  buf->msg_perm.mode >>= 16;
+      arg->msg_perm.mode >>= 16;
 #else
-  /* Old Linux kernel versions might not clear the mode padding.  */
-  if (sizeof ((struct msqid_ds){0}.msg_perm.mode)
-      != sizeof (__kernel_mode_t))
-    buf->msg_perm.mode &= 0xFFFF;
+      /* Old Linux kernel versions might not clear the mode padding.  */
+      if (sizeof ((struct msqid_ds){0}.msg_perm.mode)
+          != sizeof (__kernel_mode_t))
+ arg->msg_perm.mode &= 0xFFFF;
+#endif
+
+#if __IPC_TIME64
+      kmsqid64_to_msqid64 (arg, buf);
 #endif
- }
     }
 
   return ret;
 }
-versioned_symbol (libc, __new_msgctl, msgctl, DEFAULT_VERSION);
+#if __TIMESIZE != 64
+libc_hidden_def (__msgctl64)
+
+static void
+msqid_to_msqid64 (struct __msqid64_ds *mq64, const struct msqid_ds *mq)
+{
+  mq64->msg_perm   = mq->msg_perm;
+  mq64->msg_stime  = mq->msg_stime
+     | ((__time64_t) mq->__msg_stime_high << 32);
+  mq64->msg_rtime  = mq->msg_rtime
+     | ((__time64_t) mq->__msg_rtime_high << 32);
+  mq64->msg_ctime  = mq->msg_ctime
+     | ((__time64_t) mq->__msg_ctime_high << 32);
+  mq64->msg_qnum   = mq->msg_qnum;
+  mq64->msg_qbytes = mq->msg_qbytes;
+  mq64->msg_lspid  = mq->msg_lspid;
+  mq64->msg_lrpid  = mq->msg_lrpid;
+}
+
+static void
+msqid64_to_msqid (struct msqid_ds *mq, const struct __msqid64_ds *mq64)
+{
+  mq->msg_perm         = mq64->msg_perm;
+  mq->msg_stime        = mq64->msg_stime;
+  mq->__msg_stime_high = 0;
+  mq->msg_rtime        = mq64->msg_rtime;
+  mq->__msg_rtime_high = 0;
+  mq->msg_ctime        = mq64->msg_ctime;
+  mq->__msg_ctime_high = 0;
+  mq->msg_qnum         = mq64->msg_qnum;
+  mq->msg_qbytes       = mq64->msg_qbytes;
+  mq->msg_lspid        = mq64->msg_lspid;
+  mq->msg_lrpid        = mq64->msg_lrpid;
+}
+
+int
+__msgctl (int msqid, int cmd, struct msqid_ds *buf)
+{
+  struct __msqid64_ds msqid64, *buf64 = NULL;
+  if (buf != NULL)
+    {
+      msqid_to_msqid64 (&msqid64, buf);
+      buf64 = &msqid64;
+    }
+
+  int ret = __msgctl64 (msqid, cmd, buf64);
+  if (ret < 0)
+    return ret;
+
+  switch (cmd)
+    {
+    case IPC_STAT:
+    case MSG_STAT:
+    case MSG_STAT_ANY:
+      if (buf64 != NULL)
+        msqid64_to_msqid (buf, buf64);
+    }
+
+  return ret;
+}
+#endif
+
+#ifndef DEFAULT_VERSION
+# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T
+#  define DEFAULT_VERSION GLIBC_2_2
+# else
+#  define DEFAULT_VERSION GLIBC_2_31
+# endif
+#endif
+versioned_symbol (libc, __msgctl, msgctl, DEFAULT_VERSION);
 
 #if defined __ASSUME_SYSVIPC_BROKEN_MODE_T \
     && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_31)
@@ -90,7 +201,7 @@ int
 attribute_compat_text_section
 __msgctl_mode16 (int msqid, int cmd, struct msqid_ds *buf)
 {
-  return msgctl_syscall (msqid, cmd, buf);
+  return msgctl_syscall (msqid, cmd, (msgctl_arg_t *) buf);
 }
 compat_symbol (libc, __msgctl_mode16, msgctl, GLIBC_2_2);
 #endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
index 4ae2fbcbdc..35cc51f733 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
@@ -26,11 +26,11 @@ struct msqid_ds
 {
   struct ipc_perm msg_perm; /* structure describing operation permission */
 #if __TIMESIZE == 32
-  unsigned long int __glibc_reserved1;
+  unsigned long int __msg_stime_high;
   __time_t msg_stime; /* time of last msgsnd command */
-  unsigned long int __glibc_reserved2;
+  unsigned long int __msg_rtime_high;
   __time_t msg_rtime; /* time of last msgsnd command */
-  unsigned long int __glibc_reserved3;
+  unsigned long int __msg_ctime_high;
   __time_t msg_ctime; /* time of last change */
 #else
   __time_t msg_stime; /* time of last msgsnd command */
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/struct_kernel_msqid64_ds.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/struct_kernel_msqid64_ds.h
new file mode 100644
index 0000000000..69a63ee27a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/struct_kernel_msqid64_ds.h
@@ -0,0 +1,18 @@
+/* Analogous to kernel struct msqid64_ds used on msgctl.  */
+struct kernel_msqid64_ds
+{
+  struct ipc_perm msg_perm;
+  unsigned long msg_stime_high;
+  unsigned long msg_stime;
+  unsigned long msg_rtime_high;
+  unsigned long msg_rtime;
+  unsigned long msg_ctime_high;
+  unsigned long msg_ctime;
+  unsigned long msg_cbytes;
+  unsigned long msg_qnum;
+  unsigned long msg_qbytes;
+  __pid_t msg_lspid;
+  __pid_t msg_lrpid;
+  unsigned long __unused1;
+  unsigned long __unused2;
+};
diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c
index 3a06270242..7467d2566e 100644
--- a/sysdeps/unix/sysv/linux/semctl.c
+++ b/sysdeps/unix/sysv/linux/semctl.c
@@ -196,19 +196,11 @@ libc_hidden_def (__semctl64)
 
 /* The 64-bit time_t semid_ds version might have a different layout and
    internal field alignment.  */
-static void
-semid64_ds_to_semid_ds (struct semid_ds *ds, const struct __semid64_ds *ds64)
-{
-  ds->sem_perm = ds64->sem_perm;
-  ds->sem_otime = ds64->sem_otime;
-  ds->sem_ctime = ds64->sem_ctime;
-  ds->sem_nsems = ds64->sem_nsems;
-}
 
 static void
-semid_ds_to_semid64_ds (struct __semid64_ds *ds64, const struct semid_ds *ds)
+semid_to_semid64 (struct __semid64_ds *ds64, const struct semid_ds *ds)
 {
-  ds64->sem_perm = ds->sem_perm;
+  ds64->sem_perm  = ds->sem_perm;
   ds64->sem_otime = ds->sem_otime
     | ((__time64_t) ds->__sem_otime_high << 32);
   ds64->sem_ctime = ds->sem_ctime
@@ -216,6 +208,17 @@ semid_ds_to_semid64_ds (struct __semid64_ds *ds64, const struct semid_ds *ds)
   ds64->sem_nsems = ds->sem_nsems;
 }
 
+static void
+semid64_to_semid (struct semid_ds *ds, const struct __semid64_ds *ds64)
+{
+  ds->sem_perm         = ds64->sem_perm;
+  ds->sem_otime        = ds64->sem_otime;
+  ds->__sem_otime_high = 0;
+  ds->sem_ctime        = ds64->sem_ctime;
+  ds->__sem_ctime_high = 0;
+  ds->sem_nsems        = ds64->sem_nsems;
+}
+
 static union semun64
 semun_to_semun64 (int cmd, union semun semun, struct __semid64_ds *semid64)
 {
@@ -232,7 +235,7 @@ semun_to_semun64 (int cmd, union semun semun, struct __semid64_ds *semid64)
     case IPC_STAT:
     case IPC_SET:
       r.buf = semid64;
-      semid_ds_to_semid64_ds (r.buf, semun.buf);
+      semid_to_semid64 (r.buf, semun.buf);
 # ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
       if (cmd == IPC_SET)
  r.buf->sem_perm.mode *= 0x10000U;
@@ -282,7 +285,7 @@ __semctl (int semid, int semnum, int cmd, ...)
     case IPC_STAT:
     case SEM_STAT:
     case SEM_STAT_ANY:
-      semid64_ds_to_semid_ds (arg.buf, arg64.buf);
+      semid64_to_semid (arg.buf, arg64.buf);
     }
 
   return ret;
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h
index 71980839c7..502c23d91e 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h
@@ -26,11 +26,11 @@ struct msqid_ds
 {
   struct ipc_perm msg_perm; /* structure describing operation permission */
 #if __TIMESIZE == 32
-  unsigned long int __glibc_reserved1;
+  unsigned long int __msg_stime_high;
   __time_t msg_stime; /* time of last msgsnd command */
-  unsigned long int __glibc_reserved2;
+  unsigned long int __msg_rtime_high;
   __time_t msg_rtime; /* time of last msgsnd command */
-  unsigned long int __glibc_reserved3;
+  unsigned long int __msg_ctime_high;
   __time_t msg_ctime; /* time of last change */
 #else
   __time_t msg_stime; /* time of last msgsnd command */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/struct_kernel_msqid64_ds.h b/sysdeps/unix/sysv/linux/sparc/sparc32/struct_kernel_msqid64_ds.h
new file mode 100644
index 0000000000..69a63ee27a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/struct_kernel_msqid64_ds.h
@@ -0,0 +1,18 @@
+/* Analogous to kernel struct msqid64_ds used on msgctl.  */
+struct kernel_msqid64_ds
+{
+  struct ipc_perm msg_perm;
+  unsigned long msg_stime_high;
+  unsigned long msg_stime;
+  unsigned long msg_rtime_high;
+  unsigned long msg_rtime;
+  unsigned long msg_ctime_high;
+  unsigned long msg_ctime;
+  unsigned long msg_cbytes;
+  unsigned long msg_qnum;
+  unsigned long msg_qbytes;
+  __pid_t msg_lspid;
+  __pid_t msg_lrpid;
+  unsigned long __unused1;
+  unsigned long __unused2;
+};
diff --git a/sysdeps/unix/sysv/linux/struct_kernel_msqid64_ds.h b/sysdeps/unix/sysv/linux/struct_kernel_msqid64_ds.h
new file mode 100644
index 0000000000..a676e34a5a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/struct_kernel_msqid64_ds.h
@@ -0,0 +1,19 @@
+/* Analogous to kernel struct msqid64_ds used on msgctl.  It is only used
+   for 32-bit architectures on 64-bit time_t msgctl64 implementation.  */
+struct kernel_msqid64_ds
+{
+  struct ipc_perm msg_perm;
+  unsigned long int msg_stime;
+  unsigned long int msg_stime_high;
+  unsigned long int msg_rtime;
+  unsigned long int msg_rtime_high;
+  unsigned long int msg_ctime;
+  unsigned long int msg_ctime_high;
+  unsigned long int msg_cbytes;
+  unsigned long int msg_qnum;
+  unsigned long int  msg_qbytes;
+  __pid_t msg_lspid;
+  __pid_t msg_lrpid;
+  unsigned long int __unused4;
+  unsigned long int __unused5;
+};
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 5/7] sysvipc: Split out linux struct shmid_ds

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
This will allow us to have architectures specify their own version.

Not semantic changes expected.  Checked with a build against the
all affected ABIs.
---
 sysdeps/unix/sysv/linux/Makefile              |  1 +
 sysdeps/unix/sysv/linux/bits/shm.h            | 34 +----------
 .../sysv/linux/bits/types/struct_shmid_ds.h   | 57 +++++++++++++++++++
 3 files changed, 59 insertions(+), 33 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 505087e617..bdd187af73 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -93,6 +93,7 @@ sysdep_headers += sys/mount.h sys/acct.h \
   bits/termios-misc.h \
   bits/types/struct_semid_ds.h \
   bits/types/struct_msqid_ds.h \
+  bits/types/struct_shmid_ds.h \
   bits/ipc-perm.h
 
 tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
diff --git a/sysdeps/unix/sysv/linux/bits/shm.h b/sysdeps/unix/sysv/linux/bits/shm.h
index 113c05ee89..9ef6aeaf92 100644
--- a/sysdeps/unix/sysv/linux/bits/shm.h
+++ b/sysdeps/unix/sysv/linux/bits/shm.h
@@ -43,39 +43,7 @@ __BEGIN_DECLS
 /* Type to count number of attaches.  */
 typedef __syscall_ulong_t shmatt_t;
 
-#if __SHM_PAD_BEFORE_TIME
-# define __SHM_PAD_TIME(NAME, RES) \
-  unsigned long int __glibc_reserved ## RES; __time_t NAME
-#elif __SHM_PAD_AFTER_TIME
-# define __SHM_PAD_TIME(NAME, RES) \
-  __time_t NAME; unsigned long int __glibc_reserved ## RES
-#else
-# define __SHM_PAD_TIME(NAME, RES) \
-  __time_t NAME
-#endif
-
-/* Data structure describing a shared memory segment.  */
-struct shmid_ds
-  {
-    struct ipc_perm shm_perm; /* operation permission struct */
-#if !__SHM_SEGSZ_AFTER_TIME
-    size_t shm_segsz; /* size of segment in bytes */
-#endif
-    __SHM_PAD_TIME (shm_atime, 1); /* time of last shmat() */
-    __SHM_PAD_TIME (shm_dtime, 2); /* time of last shmdt() */
-    __SHM_PAD_TIME (shm_ctime, 3); /* time of last change by shmctl() */
-#if __SHM_PAD_BETWEEN_TIME_AND_SEGSZ
-    unsigned long int __glibc_reserved4;
-#endif
-#if __SHM_SEGSZ_AFTER_TIME
-    size_t shm_segsz; /* size of segment in bytes */
-#endif
-    __pid_t shm_cpid; /* pid of creator */
-    __pid_t shm_lpid; /* pid of last shmop */
-    shmatt_t shm_nattch; /* number of current attaches */
-    __syscall_ulong_t __glibc_reserved5;
-    __syscall_ulong_t __glibc_reserved6;
-  };
+#include <bits/types/struct_shmid_ds.h>
 
 #ifdef __USE_MISC
 
diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h
new file mode 100644
index 0000000000..938bbedfcd
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h
@@ -0,0 +1,57 @@
+/* Generic implementation of the shared memory struct shmid_ds.
+   Copyright (C) 2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/types/struct_shmid_ds.h> directly; use <sys/shm.h> instead."
+#endif
+
+#include <bits/shm-pad.h>
+
+#if __SHM_PAD_BEFORE_TIME
+# define __SHM_PAD_TIME(NAME, RES) \
+  unsigned long int __glibc_reserved ## RES; __time_t NAME
+#elif __SHM_PAD_AFTER_TIME
+# define __SHM_PAD_TIME(NAME, RES) \
+  __time_t NAME; unsigned long int __glibc_reserved ## RES
+#else
+# define __SHM_PAD_TIME(NAME, RES) \
+  __time_t NAME
+#endif
+
+/* Data structure describing a shared memory segment.  */
+struct shmid_ds
+  {
+    struct ipc_perm shm_perm; /* operation permission struct */
+#if !__SHM_SEGSZ_AFTER_TIME
+    size_t shm_segsz; /* size of segment in bytes */
+#endif
+    __SHM_PAD_TIME (shm_atime, 1); /* time of last shmat() */
+    __SHM_PAD_TIME (shm_dtime, 2); /* time of last shmdt() */
+    __SHM_PAD_TIME (shm_ctime, 3); /* time of last change by shmctl() */
+#if __SHM_PAD_BETWEEN_TIME_AND_SEGSZ
+    unsigned long int __glibc_reserved4;
+#endif
+#if __SHM_SEGSZ_AFTER_TIME
+    size_t shm_segsz; /* size of segment in bytes */
+#endif
+    __pid_t shm_cpid; /* pid of creator */
+    __pid_t shm_lpid; /* pid of last shmop */
+    shmatt_t shm_nattch; /* number of current attaches */
+    __syscall_ulong_t __glibc_reserved5;
+    __syscall_ulong_t __glibc_reserved6;
+  };
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 6/7] sysvipc: Remove the linux shm-pad.h file

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
Each architecture overrides the struct msqid_ds which its required
kernel ABI one.

Checked on x86_64-linux-gnu and some bases sysvipc tests on hppa,
mips, mipsle, mips64, mips64le, sparc64, sparcv9, powerpc64le,
powerpc64, and powerpc.
---
 sysdeps/unix/sysv/linux/Makefile              |  2 +-
 sysdeps/unix/sysv/linux/bits/shm-pad.h        | 37 --------------
 sysdeps/unix/sysv/linux/bits/shm.h            |  1 -
 .../sysv/linux/bits/types/struct_shmid_ds.h   | 34 +++++--------
 sysdeps/unix/sysv/linux/hppa/bits/shm-pad.h   | 28 -----------
 .../linux/hppa/bits/types/struct_shmid_ds.h   | 46 +++++++++++++++++
 sysdeps/unix/sysv/linux/mips/bits/shm-pad.h   | 26 ----------
 .../linux/mips/bits/types/struct_shmid_ds.h   | 49 +++++++++++++++++++
 .../unix/sysv/linux/powerpc/bits/shm-pad.h    | 28 -----------
 .../powerpc/bits/types/struct_shmid_ds.h      | 46 +++++++++++++++++
 sysdeps/unix/sysv/linux/sparc/bits/shm-pad.h  | 28 -----------
 .../linux/sparc/bits/types/struct_shmid_ds.h  | 45 +++++++++++++++++
 12 files changed, 198 insertions(+), 172 deletions(-)
 delete mode 100644 sysdeps/unix/sysv/linux/bits/shm-pad.h
 delete mode 100644 sysdeps/unix/sysv/linux/hppa/bits/shm-pad.h
 create mode 100644 sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h
 delete mode 100644 sysdeps/unix/sysv/linux/mips/bits/shm-pad.h
 create mode 100644 sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h
 delete mode 100644 sysdeps/unix/sysv/linux/powerpc/bits/shm-pad.h
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h
 delete mode 100644 sysdeps/unix/sysv/linux/sparc/bits/shm-pad.h
 create mode 100644 sysdeps/unix/sysv/linux/sparc/bits/types/struct_shmid_ds.h

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index bdd187af73..fd0c313041 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -85,7 +85,7 @@ sysdep_headers += sys/mount.h sys/acct.h \
   bits/siginfo-arch.h bits/siginfo-consts-arch.h \
   bits/procfs.h bits/procfs-id.h bits/procfs-extra.h \
   bits/procfs-prregset.h bits/mman-map-flags-generic.h \
-  bits/shmlba.h bits/shm-pad.h \
+  bits/shmlba.h \
   bits/termios-struct.h bits/termios-c_cc.h \
   bits/termios-c_iflag.h bits/termios-c_oflag.h \
   bits/termios-baud.h bits/termios-c_cflag.h \
diff --git a/sysdeps/unix/sysv/linux/bits/shm-pad.h b/sysdeps/unix/sysv/linux/bits/shm-pad.h
deleted file mode 100644
index 565e0e344b..0000000000
--- a/sysdeps/unix/sysv/linux/bits/shm-pad.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Define where padding goes in struct shmid_ds.  Generic version.
-   Copyright (C) 2018-2020 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
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef _SYS_SHM_H
-# error "Never use <bits/shm-pad.h> directly; include <sys/shm.h> instead."
-#endif
-
-#include <bits/timesize.h>
-
-/* On most architectures, padding goes after time fields for 32-bit
-   systems and is omitted for 64-bit systems.  Some architectures pad
-   before time fields instead, or omit padding despite being 32-bit,
-   or include it despite being 64-bit.  Furthermore, some
-   architectures place shm_segsz after the time fields rather than
-   before them, with or without padding there.  This must match the
-   layout used for struct shmid64_ds in <asm/shmbuf.h>, as glibc does
-   not do layout conversions for this structure.  */
-
-#define __SHM_PAD_AFTER_TIME (__TIMESIZE == 32)
-#define __SHM_PAD_BEFORE_TIME 0
-#define __SHM_SEGSZ_AFTER_TIME 0
-#define __SHM_PAD_BETWEEN_TIME_AND_SEGSZ 0
diff --git a/sysdeps/unix/sysv/linux/bits/shm.h b/sysdeps/unix/sysv/linux/bits/shm.h
index 9ef6aeaf92..f6aefa17f2 100644
--- a/sysdeps/unix/sysv/linux/bits/shm.h
+++ b/sysdeps/unix/sysv/linux/bits/shm.h
@@ -22,7 +22,6 @@
 #include <bits/types.h>
 #include <bits/wordsize.h>
 #include <bits/shmlba.h>
-#include <bits/shm-pad.h>
 
 /* Permission flag for shmget.  */
 #define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */
diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h
index 938bbedfcd..61ed4a08c3 100644
--- a/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h
+++ b/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h
@@ -20,34 +20,22 @@
 # error "Never include <bits/types/struct_shmid_ds.h> directly; use <sys/shm.h> instead."
 #endif
 
-#include <bits/shm-pad.h>
-
-#if __SHM_PAD_BEFORE_TIME
-# define __SHM_PAD_TIME(NAME, RES) \
-  unsigned long int __glibc_reserved ## RES; __time_t NAME
-#elif __SHM_PAD_AFTER_TIME
-# define __SHM_PAD_TIME(NAME, RES) \
-  __time_t NAME; unsigned long int __glibc_reserved ## RES
-#else
-# define __SHM_PAD_TIME(NAME, RES) \
-  __time_t NAME
-#endif
-
 /* Data structure describing a shared memory segment.  */
 struct shmid_ds
   {
     struct ipc_perm shm_perm; /* operation permission struct */
-#if !__SHM_SEGSZ_AFTER_TIME
-    size_t shm_segsz; /* size of segment in bytes */
-#endif
-    __SHM_PAD_TIME (shm_atime, 1); /* time of last shmat() */
-    __SHM_PAD_TIME (shm_dtime, 2); /* time of last shmdt() */
-    __SHM_PAD_TIME (shm_ctime, 3); /* time of last change by shmctl() */
-#if __SHM_PAD_BETWEEN_TIME_AND_SEGSZ
-    unsigned long int __glibc_reserved4;
-#endif
-#if __SHM_SEGSZ_AFTER_TIME
     size_t shm_segsz; /* size of segment in bytes */
+#if __TIMESIZE == 32
+    __time_t shm_atime; /* time of last shmat() */
+    unsigned long int __glibc_reserved1;
+    __time_t shm_dtime; /* time of last shmdt() */
+    unsigned long int __glibc_reserved2;
+    __time_t shm_ctime; /* time of last change by shmctl() */
+    unsigned long int __glibc_reserved3;
+#else
+    __time_t shm_atime; /* time of last shmat() */
+    __time_t shm_dtime; /* time of last shmdt() */
+    __time_t shm_ctime; /* time of last change by shmctl() */
 #endif
     __pid_t shm_cpid; /* pid of creator */
     __pid_t shm_lpid; /* pid of last shmop */
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/shm-pad.h b/sysdeps/unix/sysv/linux/hppa/bits/shm-pad.h
deleted file mode 100644
index d0811fe543..0000000000
--- a/sysdeps/unix/sysv/linux/hppa/bits/shm-pad.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Define where padding goes in struct shmid_ds.  HPPA version.
-   Copyright (C) 2018-2020 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
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef _SYS_SHM_H
-# error "Never use <bits/shm-pad.h> directly; include <sys/shm.h> instead."
-#endif
-
-#include <bits/timesize.h>
-
-#define __SHM_PAD_AFTER_TIME 0
-#define __SHM_PAD_BEFORE_TIME (__TIMESIZE == 32)
-#define __SHM_SEGSZ_AFTER_TIME 1
-#define __SHM_PAD_BETWEEN_TIME_AND_SEGSZ (__TIMESIZE == 32)
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h
new file mode 100644
index 0000000000..1ebf222eac
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h
@@ -0,0 +1,46 @@
+/* Linux/HPPA implementation of the shared memory struct shmid_ds.
+   Copyright (C) 2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/types/struct_shmid_ds.h> directly; use <sys/shm.h> instead."
+#endif
+
+/* Data structure describing a shared memory segment.  */
+struct shmid_ds
+  {
+    struct ipc_perm shm_perm; /* operation permission struct */
+#if __TIMESIZE == 32
+    unsigned long int __glibc_reserved1;
+    __time_t shm_atime; /* time of last shmat() */
+    unsigned long int __glibc_reserved2;
+    __time_t shm_dtime; /* time of last shmdt() */
+    unsigned long int __glibc_reserved3;
+    __time_t shm_ctime; /* time of last change by shmctl() */
+    unsigned long int __glibc_reserved4;
+#else
+    __time_t shm_atime; /* time of last shmat() */
+    __time_t shm_dtime; /* time of last shmdt() */
+    __time_t shm_ctime; /* time of last change by shmctl() */
+#endif
+    size_t shm_segsz; /* size of segment in bytes */
+    __pid_t shm_cpid; /* pid of creator */
+    __pid_t shm_lpid; /* pid of last shmop */
+    shmatt_t shm_nattch; /* number of current attaches */
+    __syscall_ulong_t __glibc_reserved5;
+    __syscall_ulong_t __glibc_reserved6;
+  };
diff --git a/sysdeps/unix/sysv/linux/mips/bits/shm-pad.h b/sysdeps/unix/sysv/linux/mips/bits/shm-pad.h
deleted file mode 100644
index 5a475a64f9..0000000000
--- a/sysdeps/unix/sysv/linux/mips/bits/shm-pad.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Define where padding goes in struct shmid_ds.  MIPS version.
-   Copyright (C) 2018-2020 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
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef _SYS_SHM_H
-# error "Never use <bits/shm-pad.h> directly; include <sys/shm.h> instead."
-#endif
-
-#define __SHM_PAD_AFTER_TIME 0
-#define __SHM_PAD_BEFORE_TIME 0
-#define __SHM_SEGSZ_AFTER_TIME 0
-#define __SHM_PAD_BETWEEN_TIME_AND_SEGSZ 0
diff --git a/sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h
new file mode 100644
index 0000000000..8e13928980
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h
@@ -0,0 +1,49 @@
+/* Linux/MIPS implementation of the shared memory struct shmid_ds.
+   Copyright (C) 2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/types/struct_shmid_ds.h> directly; use <sys/shm.h> instead."
+#endif
+
+/* Data structure describing a shared memory segment.  */
+struct shmid_ds
+  {
+    struct ipc_perm shm_perm; /* operation permission struct */
+    size_t shm_segsz; /* size of segment in bytes */
+#if __TIMESIZE == 32
+    __time_t shm_atime; /* time of last shmat() */
+    __time_t shm_dtime; /* time of last shmdt() */
+    __time_t shm_ctime; /* time of last change by shmctl() */
+#else
+    __time_t shm_atime; /* time of last shmat() */
+    __time_t shm_dtime; /* time of last shmdt() */
+    __time_t shm_ctime; /* time of last change by shmctl() */
+#endif
+    __pid_t shm_cpid; /* pid of creator */
+    __pid_t shm_lpid; /* pid of last shmop */
+    shmatt_t shm_nattch; /* number of current attaches */
+#if __TIMESIZE == 32
+    unsigned short int __glibc_reserved1;
+    unsigned short int __glibc_reserved2;
+    unsigned short int __glibc_reserved3;
+    unsigned short int __glibc_reserved4;
+#else
+    __syscall_ulong_t __glibc_reserved5;
+    __syscall_ulong_t __glibc_reserved6;
+#endif
+  };
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/shm-pad.h b/sysdeps/unix/sysv/linux/powerpc/bits/shm-pad.h
deleted file mode 100644
index 34cbdb2a0d..0000000000
--- a/sysdeps/unix/sysv/linux/powerpc/bits/shm-pad.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Define where padding goes in struct shmid_ds.  PowerPC version.
-   Copyright (C) 2018-2020 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
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef _SYS_SHM_H
-# error "Never use <bits/shm-pad.h> directly; include <sys/shm.h> instead."
-#endif
-
-#include <bits/timesize.h>
-
-#define __SHM_PAD_AFTER_TIME 0
-#define __SHM_PAD_BEFORE_TIME (__TIMESIZE == 32)
-#define __SHM_SEGSZ_AFTER_TIME 1
-#define __SHM_PAD_BETWEEN_TIME_AND_SEGSZ (__TIMESIZE == 32)
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h
new file mode 100644
index 0000000000..b0816fb16a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h
@@ -0,0 +1,46 @@
+/* Linux/PowerPC implementation of the shared memory struct shmid_ds.
+   Copyright (C) 2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/types/struct_shmid_ds.h> directly; use <sys/shm.h> instead."
+#endif
+
+/* Data structure describing a shared memory segment.  */
+struct shmid_ds
+  {
+    struct ipc_perm shm_perm; /* operation permission struct */
+#if __TIMESIZE == 32
+    unsigned long int __glibc_reserved1;
+    __time_t shm_atime; /* time of last shmat() */
+    unsigned long int __glibc_reserved2;
+    __time_t shm_dtime; /* time of last shmdt() */
+    unsigned long int __glibc_reserved3;
+    __time_t shm_ctime; /* time of last change by shmctl() */
+    unsigned long int __glibc_reserved4;
+#else
+    __time_t shm_atime; /* time of last shmat() */
+    __time_t shm_dtime; /* time of last shmdt() */
+    __time_t shm_ctime; /* time of last change by shmctl() */
+#endif
+    size_t shm_segsz; /* size of segment in bytes */
+    __pid_t shm_cpid; /* pid of creator */
+    __pid_t shm_lpid; /* pid of last shmop */
+    shmatt_t shm_nattch; /* number of current attaches */
+    __syscall_ulong_t __glibc_reserved5;
+    __syscall_ulong_t __glibc_reserved6;
+  };
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/shm-pad.h b/sysdeps/unix/sysv/linux/sparc/bits/shm-pad.h
deleted file mode 100644
index cd0b1fe543..0000000000
--- a/sysdeps/unix/sysv/linux/sparc/bits/shm-pad.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Define where padding goes in struct shmid_ds.  SPARC version.
-   Copyright (C) 2018-2020 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
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef _SYS_SHM_H
-# error "Never use <bits/shm-pad.h> directly; include <sys/shm.h> instead."
-#endif
-
-#include <bits/timesize.h>
-
-#define __SHM_PAD_AFTER_TIME 0
-#define __SHM_PAD_BEFORE_TIME (__TIMESIZE == 32)
-#define __SHM_SEGSZ_AFTER_TIME 1
-#define __SHM_PAD_BETWEEN_TIME_AND_SEGSZ 0
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_shmid_ds.h
new file mode 100644
index 0000000000..d5fb61d374
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_shmid_ds.h
@@ -0,0 +1,45 @@
+/* Linux/SPARC implementation of the shared memory struct shmid_ds.
+   Copyright (C) 2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/types/struct_shmid_ds.h> directly; use <sys/shm.h> instead."
+#endif
+
+/* Data structure describing a shared memory segment.  */
+struct shmid_ds
+  {
+    struct ipc_perm shm_perm; /* operation permission struct */
+#if __TIMESIZE == 32
+    unsigned long int __glibc_reserved1;
+    __time_t shm_atime; /* time of last shmat() */
+    unsigned long int __glibc_reserved2;
+    __time_t shm_dtime; /* time of last shmdt() */
+    unsigned long int __glibc_reserved3;
+    __time_t shm_ctime; /* time of last change by shmctl() */
+#else
+    __time_t shm_atime; /* time of last shmat() */
+    __time_t shm_dtime; /* time of last shmdt() */
+    __time_t shm_ctime; /* time of last change by shmctl() */
+#endif
+    size_t shm_segsz; /* size of segment in bytes */
+    __pid_t shm_cpid; /* pid of creator */
+    __pid_t shm_lpid; /* pid of last shmop */
+    shmatt_t shm_nattch; /* number of current attaches */
+    __syscall_ulong_t __glibc_reserved5;
+    __syscall_ulong_t __glibc_reserved6;
+  };
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 7/7] sysv: linux: Add 64-bit time_t variant for shmctl

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
To provide a y2038 safe interface a new symbol __shmctl64 is added
and __shmctl is change to call it instead (it adds some extra buffer
copy for the 32 bit time_t implementation).

Two two new structures are added:

  1. kernel_shmid64_ds: used internally only on 32-bit architectures
     to issue the syscall.  A handful architectures (hppa, i386, mips,
     powerpc32, and sparc32) requires specific implementation due its
     specific kernel ABI.

  2. shmid_ds64: this is only for __TIMESIZE != 64 to use along with
     the 64-bit semctl.  It is different than the kernel one because
     the exported 64-bit time_t might require different alignment
     depending of the architecture ABI.

So the resulting implementation does:

  1. For 64-bit architectures it assumes shmid_ds already contains
     64-bit time_t fields it will result in just the __shmctl symbol
     using the __shmctl64 code.  The shmid_ds argument is passed as-is
     to the syscall.

  2. For 32-bit architectures with default 64-bit time_t (newer ABIs
     such riscv32 or arc), it will also result in only one exported
     symbol but with the required high/low time handling.

  3. Finally for 32-bit architecture with both 32-bit and 64-bit time_t
     support we follow the already set way to provide one symbol with
     64-bit time_t support and implement the 32-bit time_t support on
     basis of the 64-bit one.

     The default 32-bit symbol will allocate and copy the shmid_ds
     over multiple buffers, but this should be deprecated in favor
     of the __shmctl64 anyway.

Checked on i686-linux-gnu and x86_64-linux-gnu.  I also did some sniff
tests on powerpc, powerpc64, mips, mips64, armhf, sparcv9, and
sparc64.
---
 include/sys/shm.h                             |  16 ++
 .../sysv/linux/bits/types/struct_shmid64_ds.h |  37 ++++
 .../sysv/linux/bits/types/struct_shmid_ds.h   |   6 +-
 .../linux/hppa/bits/types/struct_shmid_ds.h   |   6 +-
 .../linux/hppa/struct_kernel_shmid64_ds.h     |  18 ++
 .../linux/i386/struct_kernel_shmid64_ds.h     |  17 ++
 .../linux/mips/bits/types/struct_shmid_ds.h   |   6 +-
 .../linux/mips/struct_kernel_shmid64_ds.h     |  27 +++
 .../powerpc/bits/types/struct_shmid_ds.h      |   6 +-
 .../linux/powerpc/struct_kernel_shmid64_ds.h  |  24 +++
 sysdeps/unix/sysv/linux/shmctl.c              | 180 ++++++++++++++----
 .../linux/sparc/bits/types/struct_shmid_ds.h  |   6 +-
 .../linux/sparc/struct_kernel_shmid64_ds.h    |  23 +++
 .../sysv/linux/struct_kernel_shmid64_ds.h     |  23 +++
 14 files changed, 346 insertions(+), 49 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/bits/types/struct_shmid64_ds.h
 create mode 100644 sysdeps/unix/sysv/linux/hppa/struct_kernel_shmid64_ds.h
 create mode 100644 sysdeps/unix/sysv/linux/i386/struct_kernel_shmid64_ds.h
 create mode 100644 sysdeps/unix/sysv/linux/mips/struct_kernel_shmid64_ds.h
 create mode 100644 sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h
 create mode 100644 sysdeps/unix/sysv/linux/sparc/struct_kernel_shmid64_ds.h
 create mode 100644 sysdeps/unix/sysv/linux/struct_kernel_shmid64_ds.h

diff --git a/include/sys/shm.h b/include/sys/shm.h
index 1878fcc5be..530a1cdfc9 100644
--- a/include/sys/shm.h
+++ b/include/sys/shm.h
@@ -1 +1,17 @@
+#ifndef _SYS_SHM_H
 #include <sysvipc/sys/shm.h>
+
+#ifndef _ISOMAC
+
+# include <bits/types/struct_shmid64_ds.h>
+
+# if __TIMESIZE == 64
+#  define __shmctl64 __shmctl
+# else
+extern int __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf);
+libc_hidden_proto (__shmctl64);
+# endif
+
+#endif /* _ISOMAC  */
+
+#endif /* _SYS_SHM_H  */
diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_shmid64_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_shmid64_ds.h
new file mode 100644
index 0000000000..f71e0d28ff
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/bits/types/struct_shmid64_ds.h
@@ -0,0 +1,37 @@
+/* Generic implementation of the shared memory struct shmid_ds.
+   Copyright (C) 2020 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/types/struct_shmid_ds.h> directly; use <sys/shm.h> instead."
+#endif
+
+#if __TIMESIZE == 64
+# define __shmid64_ds shmid_ds
+#else
+struct __shmid64_ds
+{
+  struct ipc_perm shm_perm; /* operation permission struct */
+  size_t shm_segsz; /* size of segment in bytes */
+  __time64_t shm_atime; /* time of last shmat() */
+  __time64_t shm_dtime; /* time of last shmdt() */
+  __time64_t shm_ctime; /* time of last change by shmctl() */
+  __pid_t shm_cpid; /* pid of creator */
+  __pid_t shm_lpid; /* pid of last shmop */
+  shmatt_t shm_nattch; /* number of current attaches */
+};
+#endif
diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h
index 61ed4a08c3..836a7d50e9 100644
--- a/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h
+++ b/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h
@@ -27,11 +27,11 @@ struct shmid_ds
     size_t shm_segsz; /* size of segment in bytes */
 #if __TIMESIZE == 32
     __time_t shm_atime; /* time of last shmat() */
-    unsigned long int __glibc_reserved1;
+    unsigned long int __shm_atime_high;
     __time_t shm_dtime; /* time of last shmdt() */
-    unsigned long int __glibc_reserved2;
+    unsigned long int __shm_dtime_high;
     __time_t shm_ctime; /* time of last change by shmctl() */
-    unsigned long int __glibc_reserved3;
+    unsigned long int __shm_ctime_high;
 #else
     __time_t shm_atime; /* time of last shmat() */
     __time_t shm_dtime; /* time of last shmdt() */
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h
index 1ebf222eac..1abed1e149 100644
--- a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h
+++ b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h
@@ -25,11 +25,11 @@ struct shmid_ds
   {
     struct ipc_perm shm_perm; /* operation permission struct */
 #if __TIMESIZE == 32
-    unsigned long int __glibc_reserved1;
+    unsigned long int __shm_atime_high;
     __time_t shm_atime; /* time of last shmat() */
-    unsigned long int __glibc_reserved2;
+    unsigned long int __shm_dtime_high;
     __time_t shm_dtime; /* time of last shmdt() */
-    unsigned long int __glibc_reserved3;
+    unsigned long int __shm_ctime_high;
     __time_t shm_ctime; /* time of last change by shmctl() */
     unsigned long int __glibc_reserved4;
 #else
diff --git a/sysdeps/unix/sysv/linux/hppa/struct_kernel_shmid64_ds.h b/sysdeps/unix/sysv/linux/hppa/struct_kernel_shmid64_ds.h
new file mode 100644
index 0000000000..4d09fc7f62
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/struct_kernel_shmid64_ds.h
@@ -0,0 +1,18 @@
+/* Analogous to kernel struct shmid64_ds used on shmctl.  */
+struct kernel_shmid64_ds
+{
+  struct ipc_perm shm_perm; /* operation permission struct */
+  unsigned long int shm_atime_high;
+  unsigned long int shm_atime; /* time of last shmat() */
+  unsigned long int shm_dtime_high;
+  unsigned long int shm_dtime; /* time of last shmdt() */
+  unsigned long int shm_ctime_high;
+  unsigned long int shm_ctime; /* time of last change by shmctl() */
+  unsigned long int __pad;
+  size_t shm_segsz; /* size of segment in bytes */
+  __pid_t shm_cpid; /* pid of creator */
+  __pid_t shm_lpid; /* pid of last shmop */
+  shmatt_t shm_nattch; /* number of current attaches */
+  unsigned long int __unused1;
+  unsigned long int __unused2;
+};
diff --git a/sysdeps/unix/sysv/linux/i386/struct_kernel_shmid64_ds.h b/sysdeps/unix/sysv/linux/i386/struct_kernel_shmid64_ds.h
new file mode 100644
index 0000000000..6a0a0d9c71
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/struct_kernel_shmid64_ds.h
@@ -0,0 +1,17 @@
+/* Analogous to kernel struct compat_shmid64_ds used on shmctl.  */
+struct kernel_shmid64_ds
+{
+  struct ipc_perm shm_perm;
+  size_t shm_segsz;
+  unsigned long int shm_atime;
+  unsigned long int shm_atime_high;
+  unsigned long int shm_dtime;
+  unsigned long int shm_dtime_high;
+  unsigned long int shm_ctime;
+  unsigned long int shm_ctime_high;
+  __pid_t shm_cpid;
+  __pid_t shm_lpid;
+  unsigned long int shm_nattch;
+  unsigned long int __unused4;
+  unsigned long int __unused5;
+};
diff --git a/sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h
index 8e13928980..58090e2fcb 100644
--- a/sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h
+++ b/sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h
@@ -38,9 +38,9 @@ struct shmid_ds
     __pid_t shm_lpid; /* pid of last shmop */
     shmatt_t shm_nattch; /* number of current attaches */
 #if __TIMESIZE == 32
-    unsigned short int __glibc_reserved1;
-    unsigned short int __glibc_reserved2;
-    unsigned short int __glibc_reserved3;
+    unsigned short int __shm_atime_high;
+    unsigned short int __shm_dtime_high;
+    unsigned short int __shm_ctime_high;
     unsigned short int __glibc_reserved4;
 #else
     __syscall_ulong_t __glibc_reserved5;
diff --git a/sysdeps/unix/sysv/linux/mips/struct_kernel_shmid64_ds.h b/sysdeps/unix/sysv/linux/mips/struct_kernel_shmid64_ds.h
new file mode 100644
index 0000000000..a4baa5614f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/struct_kernel_shmid64_ds.h
@@ -0,0 +1,27 @@
+/* Analogous to kernel struct shmid64_ds used on shmctl.  */
+struct kernel_shmid64_ds
+{
+  struct ipc_perm shm_perm;
+  size_t shm_segsz;
+#if __TIMESIZE == 64
+  long int shm_atime;
+  long int shm_dtime;
+  long int shm_ctime;
+#else
+  unsigned long int shm_atime;
+  unsigned long int shm_dtime;
+  unsigned long int shm_ctime;
+#endif
+  __pid_t shm_cpid;
+  __pid_t shm_lpid;
+  unsigned long int shm_nattch;
+#if __TIMESIZE == 64
+  unsigned long int __unused1;
+  unsigned long int __unused2;
+#else
+  unsigned short int shm_atime_high;
+  unsigned short int shm_dtime_high;
+  unsigned short int shm_ctime_high;
+  unsigned short int __ununsed1;
+#endif
+};
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h
index b0816fb16a..39b3e5fd3e 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h
@@ -25,11 +25,11 @@ struct shmid_ds
   {
     struct ipc_perm shm_perm; /* operation permission struct */
 #if __TIMESIZE == 32
-    unsigned long int __glibc_reserved1;
+    unsigned long int __shm_atime_high;
     __time_t shm_atime; /* time of last shmat() */
-    unsigned long int __glibc_reserved2;
+    unsigned long int __shm_dtime_high;
     __time_t shm_dtime; /* time of last shmdt() */
-    unsigned long int __glibc_reserved3;
+    unsigned long int __shm_ctime_high;
     __time_t shm_ctime; /* time of last change by shmctl() */
     unsigned long int __glibc_reserved4;
 #else
diff --git a/sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h b/sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h
new file mode 100644
index 0000000000..5533d44dee
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h
@@ -0,0 +1,24 @@
+/* Analogous to kernel struct shmid64_ds used on shmctl.  */
+struct kernel_shmid64_ds
+{
+  struct ipc_perm shm_perm;
+#if __TIMESIZE == 64
+  long int shm_atime;
+  long int shm_atime;
+  long int shm_atime;
+#else
+  unsigned long int shm_atime_high;
+  unsigned long int shm_atime;
+  unsigned long int shm_dtime_high;
+  unsigned long int shm_dtime;
+  unsigned long int shm_ctime_high;
+  unsigned long int shm_ctime;
+  unsigned long int __ununsed1;
+#endif
+  size_t shm_segsz;
+  __pid_t shm_cpid;
+  __pid_t shm_lpid;
+  unsigned long int shm_nattch;
+  unsigned long int __unused2;
+  unsigned long int __unused3;
+};
diff --git a/sysdeps/unix/sysv/linux/shmctl.c b/sysdeps/unix/sysv/linux/shmctl.c
index f41b359b8b..aaf3946054 100644
--- a/sysdeps/unix/sysv/linux/shmctl.c
+++ b/sysdeps/unix/sysv/linux/shmctl.c
@@ -24,16 +24,55 @@
 #include <errno.h>
 #include <linux/posix_types.h>  /* For __kernel_mode_t.  */
 
-#ifndef DEFAULT_VERSION
-# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T
-#  define DEFAULT_VERSION GLIBC_2_2
-# else
-#  define DEFAULT_VERSION GLIBC_2_31
-# endif
+/* POSIX states ipc_perm mode should have type of mode_t.  */
+_Static_assert (sizeof ((struct shmid_ds){0}.shm_perm.mode)
+ == sizeof (mode_t),
+ "sizeof (shmid_ds.shm_perm.mode) != sizeof (mode_t)");
+
+#if __IPC_TIME64 == 0
+typedef struct shmid_ds shmctl_arg_t;
+#else
+# include <struct_kernel_shmid64_ds.h>
+
+static void
+shmid64_to_kshmid64 (const struct __shmid64_ds *shmid64,
+     struct kernel_shmid64_ds *kshmid)
+{
+  kshmid->shm_perm       = shmid64->shm_perm;
+  kshmid->shm_segsz      = shmid64->shm_segsz;
+  kshmid->shm_atime      = shmid64->shm_atime;
+  kshmid->shm_atime_high = shmid64->shm_atime >> 32;
+  kshmid->shm_dtime      = shmid64->shm_dtime;
+  kshmid->shm_dtime_high = shmid64->shm_dtime >> 32;
+  kshmid->shm_ctime      = shmid64->shm_ctime;
+  kshmid->shm_ctime_high = shmid64->shm_ctime >> 32;
+  kshmid->shm_cpid       = shmid64->shm_cpid;
+  kshmid->shm_lpid       = shmid64->shm_lpid;
+  kshmid->shm_nattch     = shmid64->shm_nattch;
+}
+
+static void
+kshmid64_to_shmid64 (const struct kernel_shmid64_ds *kshmid,
+     struct __shmid64_ds *shmid64)
+{
+  shmid64->shm_perm   = kshmid->shm_perm;
+  shmid64->shm_segsz  = kshmid->shm_segsz;
+  shmid64->shm_atime  = kshmid->shm_atime
+        | ((__time64_t) kshmid->shm_atime_high << 32);
+  shmid64->shm_dtime  = kshmid->shm_dtime
+        | ((__time64_t) kshmid->shm_dtime_high << 32);
+  shmid64->shm_ctime     = kshmid->shm_ctime
+        | ((__time64_t) kshmid->shm_ctime_high << 32);
+  shmid64->shm_cpid   = kshmid->shm_cpid;
+  shmid64->shm_lpid   = kshmid->shm_lpid;
+  shmid64->shm_nattch = kshmid->shm_nattch;
+}
+
+typedef struct kernel_shmid64_ds shmctl_arg_t;
 #endif
 
 static int
-shmctl_syscall (int shmid, int cmd, struct shmid_ds *buf)
+shmctl_syscall (int shmid, int cmd, shmctl_arg_t *buf)
 {
 #ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
   return INLINE_SYSCALL_CALL (shmctl, shmid, cmd | __IPC_64, buf);
@@ -45,46 +84,119 @@ shmctl_syscall (int shmid, int cmd, struct shmid_ds *buf)
 
 /* Provide operations to control over shared memory segments.  */
 int
-__new_shmctl (int shmid, int cmd, struct shmid_ds *buf)
+__shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf)
 {
-  /* POSIX states ipc_perm mode should have type of mode_t.  */
-  _Static_assert (sizeof ((struct shmid_ds){0}.shm_perm.mode)
-  == sizeof (mode_t),
-  "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)");
-
-#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
-  struct shmid_ds tmpds;
-  if (cmd == IPC_SET)
+#if __IPC_TIME64
+  struct kernel_shmid64_ds kshmid, *arg = NULL;
+  if (buf != NULL)
     {
-      tmpds = *buf;
-      tmpds.shm_perm.mode *= 0x10000U;
-      buf = &tmpds;
+      shmid64_to_kshmid64 (buf, &kshmid);
+      arg = &kshmid;
     }
+# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
+  if (cmd == IPC_SET)
+      arg->shm_perm.mode *= 0x10000U;
+# endif
+#else
+  shmctl_arg_t *arg = buf;
 #endif
 
-  int ret = shmctl_syscall (shmid, cmd, buf);
+  int ret = shmctl_syscall (shmid, cmd, arg);
+  if (ret < 0)
+    return ret;
 
-  if (ret >= 0)
+  switch (cmd)
     {
-      switch (cmd)
- {
-        case IPC_STAT:
-        case SHM_STAT:
-        case SHM_STAT_ANY:
+      case IPC_STAT:
+      case SHM_STAT:
+      case SHM_STAT_ANY:
 #ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
-          buf->shm_perm.mode >>= 16;
+        arg->shm_perm.mode >>= 16;
 #else
-  /* Old Linux kernel versions might not clear the mode padding.  */
-  if (sizeof ((struct shmid_ds){0}.shm_perm.mode)
-      != sizeof (__kernel_mode_t))
-    buf->shm_perm.mode &= 0xFFFF;
+      /* Old Linux kernel versions might not clear the mode padding.  */
+      if (sizeof ((struct shmid_ds){0}.shm_perm.mode)
+  != sizeof (__kernel_mode_t))
+ arg->shm_perm.mode &= 0xFFFF;
+#endif
+
+#if __IPC_TIME64
+      kshmid64_to_shmid64 (arg, buf);
 #endif
- }
     }
 
   return ret;
 }
-versioned_symbol (libc, __new_shmctl, shmctl, DEFAULT_VERSION);
+#if __TIMESIZE != 64
+libc_hidden_def (__shmctl64)
+
+static void
+shmid_to_shmid64 (struct __shmid64_ds *shm64, const struct shmid_ds *shm)
+{
+  shm64->shm_perm   = shm->shm_perm;
+  shm64->shm_segsz  = shm->shm_segsz;
+  shm64->shm_atime  = shm->shm_atime
+        | ((__time64_t) shm->__shm_atime_high << 32);
+  shm64->shm_dtime  = shm->shm_dtime
+        | ((__time64_t) shm->__shm_dtime_high << 32);
+  shm64->shm_ctime     = shm->shm_ctime
+        | ((__time64_t) shm->__shm_ctime_high << 32);
+  shm64->shm_cpid   = shm->shm_cpid;
+  shm64->shm_lpid   = shm->shm_lpid;
+  shm64->shm_nattch = shm->shm_nattch;
+}
+
+static void
+shmid64_to_shmid (struct shmid_ds *shm, const struct __shmid64_ds *shm64)
+{
+  shm->shm_perm         = shm64->shm_perm;
+  shm->shm_segsz        = shm64->shm_segsz;
+  shm->shm_atime        = shm64->shm_atime;
+  shm->__shm_atime_high = 0;
+  shm->shm_dtime        = shm64->shm_dtime;
+  shm->__shm_dtime_high = 0;
+  shm->shm_ctime        = shm64->shm_ctime;
+  shm->__shm_ctime_high = 0;
+  shm->shm_cpid         = shm64->shm_cpid;
+  shm->shm_lpid         = shm64->shm_lpid;
+  shm->shm_nattch       = shm64->shm_nattch;
+}
+
+int
+__shmctl (int shmid, int cmd, struct shmid_ds *buf)
+{
+  struct __shmid64_ds shmid64, *buf64 = NULL;
+  if (buf != NULL)
+    {
+      shmid_to_shmid64 (&shmid64, buf);
+      buf64 = &shmid64;
+    }
+
+  int ret = __shmctl64 (shmid, cmd, buf64);
+  if (ret < 0)
+    return ret;
+
+  switch (cmd)
+    {
+      case IPC_STAT:
+      case SHM_STAT:
+      case SHM_STAT_ANY:
+ if (buf64 != NULL)
+  shmid64_to_shmid (buf, buf64);
+    }
+
+  return ret;
+}
+#endif
+
+#ifndef DEFAULT_VERSION
+# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T
+#  define DEFAULT_VERSION GLIBC_2_2
+# else
+#  define DEFAULT_VERSION GLIBC_2_31
+# endif
+#endif
+
+versioned_symbol (libc, __shmctl, shmctl, DEFAULT_VERSION);
 
 #if defined __ASSUME_SYSVIPC_BROKEN_MODE_T \
     && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_31)
@@ -92,7 +204,7 @@ int
 attribute_compat_text_section
 __shmctl_mode16 (int shmid, int cmd, struct shmid_ds *buf)
 {
-  return shmctl_syscall (shmid, cmd, buf);
+  return shmctl_syscall (shmid, cmd, (shmctl_arg_t *) buf);
 }
 compat_symbol (libc, __shmctl_mode16, shmctl, GLIBC_2_2);
 #endif
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_shmid_ds.h
index d5fb61d374..cab3a2686f 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_shmid_ds.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_shmid_ds.h
@@ -25,11 +25,11 @@ struct shmid_ds
   {
     struct ipc_perm shm_perm; /* operation permission struct */
 #if __TIMESIZE == 32
-    unsigned long int __glibc_reserved1;
+    unsigned long int __shm_atime_high;
     __time_t shm_atime; /* time of last shmat() */
-    unsigned long int __glibc_reserved2;
+    unsigned long int __shm_dtime_high;
     __time_t shm_dtime; /* time of last shmdt() */
-    unsigned long int __glibc_reserved3;
+    unsigned long int __shm_ctime_high;
     __time_t shm_ctime; /* time of last change by shmctl() */
 #else
     __time_t shm_atime; /* time of last shmat() */
diff --git a/sysdeps/unix/sysv/linux/sparc/struct_kernel_shmid64_ds.h b/sysdeps/unix/sysv/linux/sparc/struct_kernel_shmid64_ds.h
new file mode 100644
index 0000000000..c9ecd7b1e9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/struct_kernel_shmid64_ds.h
@@ -0,0 +1,23 @@
+/* Analogous to kernel struct shmid64_ds used on shmctl.  */
+struct kernel_shmid64_ds
+{
+  struct ipc_perm shm_perm;
+#if __TIMESIZE == 64
+  long int shm_atime;
+  long int shm_atime;
+  long int shm_atime;
+#else
+  unsigned long int shm_atime_high;
+  unsigned long int shm_atime;
+  unsigned long int shm_dtime_high;
+  unsigned long int shm_dtime;
+  unsigned long int shm_ctime_high;
+  unsigned long int shm_ctime;
+#endif
+  size_t shm_segsz;
+  __pid_t shm_cpid;
+  __pid_t shm_lpid;
+  unsigned long int shm_nattch;
+  unsigned long int __unused1;
+  unsigned long int __unused2;
+};
diff --git a/sysdeps/unix/sysv/linux/struct_kernel_shmid64_ds.h b/sysdeps/unix/sysv/linux/struct_kernel_shmid64_ds.h
new file mode 100644
index 0000000000..395b61e7b2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/struct_kernel_shmid64_ds.h
@@ -0,0 +1,23 @@
+/* Analogous to kernel struct shmid64_ds used on shmctl.  */
+struct kernel_shmid64_ds
+{
+  struct ipc_perm shm_perm;
+  size_t shm_segsz;
+#if __TIMESIZE == 64
+  long int shm_atime;
+  long int shm_atime;
+  long int shm_atime;
+#else
+  unsigned long int shm_atime;
+  unsigned long int shm_atime_high;
+  unsigned long int shm_dtime;
+  unsigned long int shm_dtime_high;
+  unsigned long int shm_ctime;
+  unsigned long int shm_ctime_high;
+#endif
+  __pid_t shm_cpid;
+  __pid_t shm_lpid;
+  unsigned long int shm_nattch;
+  unsigned long int __unused1;
+  unsigned long int __unused2;
+};
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 7/7] sysv: linux: Add 64-bit time_t variant for shmctl

Sourceware - libc-alpha mailing list
On Tue, Jun 30, 2020 at 12:28 PM Adhemerval Zanella via Libc-alpha
<[hidden email]> wrote:

>
> To provide a y2038 safe interface a new symbol __shmctl64 is added
> and __shmctl is change to call it instead (it adds some extra buffer
> copy for the 32 bit time_t implementation).
>
> Two two new structures are added:
>
>   1. kernel_shmid64_ds: used internally only on 32-bit architectures
>      to issue the syscall.  A handful architectures (hppa, i386, mips,
>      powerpc32, and sparc32) requires specific implementation due its
>      specific kernel ABI.
>
>   2. shmid_ds64: this is only for __TIMESIZE != 64 to use along with
>      the 64-bit semctl.  It is different than the kernel one because
>      the exported 64-bit time_t might require different alignment
>      depending of the architecture ABI.
>
> So the resulting implementation does:
>
>   1. For 64-bit architectures it assumes shmid_ds already contains
>      64-bit time_t fields it will result in just the __shmctl symbol
>      using the __shmctl64 code.  The shmid_ds argument is passed as-is
>      to the syscall.
>
>   2. For 32-bit architectures with default 64-bit time_t (newer ABIs
>      such riscv32 or arc), it will also result in only one exported
>      symbol but with the required high/low time handling.
>
>   3. Finally for 32-bit architecture with both 32-bit and 64-bit time_t
>      support we follow the already set way to provide one symbol with
>      64-bit time_t support and implement the 32-bit time_t support on
>      basis of the 64-bit one.
>
>      The default 32-bit symbol will allocate and copy the shmid_ds
>      over multiple buffers, but this should be deprecated in favor
>      of the __shmctl64 anyway.
>
> Checked on i686-linux-gnu and x86_64-linux-gnu.  I also did some sniff
> tests on powerpc, powerpc64, mips, mips64, armhf, sparcv9, and
> sparc64.
> ---
>  include/sys/shm.h                             |  16 ++
>  .../sysv/linux/bits/types/struct_shmid64_ds.h |  37 ++++
>  .../sysv/linux/bits/types/struct_shmid_ds.h   |   6 +-
>  .../linux/hppa/bits/types/struct_shmid_ds.h   |   6 +-
>  .../linux/hppa/struct_kernel_shmid64_ds.h     |  18 ++
>  .../linux/i386/struct_kernel_shmid64_ds.h     |  17 ++
>  .../linux/mips/bits/types/struct_shmid_ds.h   |   6 +-
>  .../linux/mips/struct_kernel_shmid64_ds.h     |  27 +++
>  .../powerpc/bits/types/struct_shmid_ds.h      |   6 +-
>  .../linux/powerpc/struct_kernel_shmid64_ds.h  |  24 +++
>  sysdeps/unix/sysv/linux/shmctl.c              | 180 ++++++++++++++----
>  .../linux/sparc/bits/types/struct_shmid_ds.h  |   6 +-
>  .../linux/sparc/struct_kernel_shmid64_ds.h    |  23 +++
>  .../sysv/linux/struct_kernel_shmid64_ds.h     |  23 +++
>  14 files changed, 346 insertions(+), 49 deletions(-)
>  create mode 100644 sysdeps/unix/sysv/linux/bits/types/struct_shmid64_ds.h
>  create mode 100644 sysdeps/unix/sysv/linux/hppa/struct_kernel_shmid64_ds.h
>  create mode 100644 sysdeps/unix/sysv/linux/i386/struct_kernel_shmid64_ds.h
>  create mode 100644 sysdeps/unix/sysv/linux/mips/struct_kernel_shmid64_ds.h
>  create mode 100644 sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h
>  create mode 100644 sysdeps/unix/sysv/linux/sparc/struct_kernel_shmid64_ds.h
>  create mode 100644 sysdeps/unix/sysv/linux/struct_kernel_shmid64_ds.h
>
> diff --git a/include/sys/shm.h b/include/sys/shm.h
> index 1878fcc5be..530a1cdfc9 100644
> --- a/include/sys/shm.h
> +++ b/include/sys/shm.h
> @@ -1 +1,17 @@
> +#ifndef _SYS_SHM_H
>  #include <sysvipc/sys/shm.h>
> +
> +#ifndef _ISOMAC
> +
> +# include <bits/types/struct_shmid64_ds.h>
> +
> +# if __TIMESIZE == 64
> +#  define __shmctl64 __shmctl
> +# else
> +extern int __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf);
> +libc_hidden_proto (__shmctl64);
> +# endif
> +
> +#endif /* _ISOMAC  */
> +
> +#endif /* _SYS_SHM_H  */
> diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_shmid64_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_shmid64_ds.h
> new file mode 100644
> index 0000000000..f71e0d28ff
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/bits/types/struct_shmid64_ds.h
> @@ -0,0 +1,37 @@
> +/* Generic implementation of the shared memory struct shmid_ds.
> +   Copyright (C) 2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _SYS_SHM_H
> +# error "Never include <bits/types/struct_shmid_ds.h> directly; use <sys/shm.h> instead."
> +#endif
> +
> +#if __TIMESIZE == 64
> +# define __shmid64_ds shmid_ds
> +#else
> +struct __shmid64_ds
> +{
> +  struct ipc_perm shm_perm;    /* operation permission struct */
> +  size_t shm_segsz;            /* size of segment in bytes */
> +  __time64_t shm_atime;                /* time of last shmat() */
> +  __time64_t shm_dtime;                /* time of last shmdt() */
> +  __time64_t shm_ctime;                /* time of last change by shmctl() */
> +  __pid_t shm_cpid;            /* pid of creator */
> +  __pid_t shm_lpid;            /* pid of last shmop */
> +  shmatt_t shm_nattch;         /* number of current attaches */
> +};
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h
> index 61ed4a08c3..836a7d50e9 100644
> --- a/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h
> +++ b/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h
> @@ -27,11 +27,11 @@ struct shmid_ds
>      size_t shm_segsz;                  /* size of segment in bytes */
>  #if __TIMESIZE == 32
>      __time_t shm_atime;                        /* time of last shmat() */
> -    unsigned long int __glibc_reserved1;
> +    unsigned long int __shm_atime_high;
>      __time_t shm_dtime;                        /* time of last shmdt() */
> -    unsigned long int __glibc_reserved2;
> +    unsigned long int __shm_dtime_high;
>      __time_t shm_ctime;                        /* time of last change by shmctl() */
> -    unsigned long int __glibc_reserved3;
> +    unsigned long int __shm_ctime_high;
>  #else
>      __time_t shm_atime;                        /* time of last shmat() */
>      __time_t shm_dtime;                        /* time of last shmdt() */
> diff --git a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h
> index 1ebf222eac..1abed1e149 100644
> --- a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h
> +++ b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_shmid_ds.h
> @@ -25,11 +25,11 @@ struct shmid_ds
>    {
>      struct ipc_perm shm_perm;          /* operation permission struct */
>  #if __TIMESIZE == 32
> -    unsigned long int __glibc_reserved1;
> +    unsigned long int __shm_atime_high;
>      __time_t shm_atime;                        /* time of last shmat() */
> -    unsigned long int __glibc_reserved2;
> +    unsigned long int __shm_dtime_high;
>      __time_t shm_dtime;                        /* time of last shmdt() */
> -    unsigned long int __glibc_reserved3;
> +    unsigned long int __shm_ctime_high;
>      __time_t shm_ctime;                        /* time of last change by shmctl() */
>      unsigned long int __glibc_reserved4;
>  #else
> diff --git a/sysdeps/unix/sysv/linux/hppa/struct_kernel_shmid64_ds.h b/sysdeps/unix/sysv/linux/hppa/struct_kernel_shmid64_ds.h
> new file mode 100644
> index 0000000000..4d09fc7f62
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/hppa/struct_kernel_shmid64_ds.h
> @@ -0,0 +1,18 @@
> +/* Analogous to kernel struct shmid64_ds used on shmctl.  */
> +struct kernel_shmid64_ds
> +{
> +  struct ipc_perm shm_perm;            /* operation permission struct */
> +  unsigned long int shm_atime_high;
> +  unsigned long int shm_atime;         /* time of last shmat() */
> +  unsigned long int shm_dtime_high;
> +  unsigned long int shm_dtime;         /* time of last shmdt() */
> +  unsigned long int shm_ctime_high;
> +  unsigned long int shm_ctime;         /* time of last change by shmctl() */
> +  unsigned long int __pad;
> +  size_t shm_segsz;                    /* size of segment in bytes */
> +  __pid_t shm_cpid;                    /* pid of creator */
> +  __pid_t shm_lpid;                    /* pid of last shmop */
> +  shmatt_t shm_nattch;         /* number of current attaches */
> +  unsigned long int __unused1;
> +  unsigned long int __unused2;
> +};
> diff --git a/sysdeps/unix/sysv/linux/i386/struct_kernel_shmid64_ds.h b/sysdeps/unix/sysv/linux/i386/struct_kernel_shmid64_ds.h
> new file mode 100644
> index 0000000000..6a0a0d9c71
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/i386/struct_kernel_shmid64_ds.h
> @@ -0,0 +1,17 @@
> +/* Analogous to kernel struct compat_shmid64_ds used on shmctl.  */
> +struct kernel_shmid64_ds
> +{
> +  struct ipc_perm shm_perm;
> +  size_t shm_segsz;
> +  unsigned long int shm_atime;
> +  unsigned long int shm_atime_high;
> +  unsigned long int shm_dtime;
> +  unsigned long int shm_dtime_high;
> +  unsigned long int shm_ctime;
> +  unsigned long int shm_ctime_high;
> +  __pid_t shm_cpid;
> +  __pid_t shm_lpid;
> +  unsigned long int shm_nattch;
> +  unsigned long int __unused4;
> +  unsigned long int __unused5;
> +};
> diff --git a/sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h
> index 8e13928980..58090e2fcb 100644
> --- a/sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h
> +++ b/sysdeps/unix/sysv/linux/mips/bits/types/struct_shmid_ds.h
> @@ -38,9 +38,9 @@ struct shmid_ds
>      __pid_t shm_lpid;                  /* pid of last shmop */
>      shmatt_t shm_nattch;               /* number of current attaches */
>  #if __TIMESIZE == 32
> -    unsigned short int __glibc_reserved1;
> -    unsigned short int __glibc_reserved2;
> -    unsigned short int __glibc_reserved3;
> +    unsigned short int __shm_atime_high;
> +    unsigned short int __shm_dtime_high;
> +    unsigned short int __shm_ctime_high;
>      unsigned short int __glibc_reserved4;
>  #else
>      __syscall_ulong_t __glibc_reserved5;
> diff --git a/sysdeps/unix/sysv/linux/mips/struct_kernel_shmid64_ds.h b/sysdeps/unix/sysv/linux/mips/struct_kernel_shmid64_ds.h
> new file mode 100644
> index 0000000000..a4baa5614f
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/mips/struct_kernel_shmid64_ds.h
> @@ -0,0 +1,27 @@
> +/* Analogous to kernel struct shmid64_ds used on shmctl.  */
> +struct kernel_shmid64_ds
> +{
> +  struct ipc_perm shm_perm;
> +  size_t shm_segsz;
> +#if __TIMESIZE == 64
> +  long int shm_atime;
> +  long int shm_dtime;
> +  long int shm_ctime;
> +#else
> +  unsigned long int shm_atime;
> +  unsigned long int shm_dtime;
> +  unsigned long int shm_ctime;
> +#endif
> +  __pid_t shm_cpid;
> +  __pid_t shm_lpid;
> +  unsigned long int shm_nattch;
> +#if __TIMESIZE == 64
> +  unsigned long int __unused1;
> +  unsigned long int __unused2;
> +#else
> +  unsigned short int shm_atime_high;
> +  unsigned short int shm_dtime_high;
> +  unsigned short int shm_ctime_high;
> +  unsigned short int __ununsed1;
> +#endif
> +};
> diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h
> index b0816fb16a..39b3e5fd3e 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h
> +++ b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_shmid_ds.h
> @@ -25,11 +25,11 @@ struct shmid_ds
>    {
>      struct ipc_perm shm_perm;          /* operation permission struct */
>  #if __TIMESIZE == 32
> -    unsigned long int __glibc_reserved1;
> +    unsigned long int __shm_atime_high;
>      __time_t shm_atime;                        /* time of last shmat() */
> -    unsigned long int __glibc_reserved2;
> +    unsigned long int __shm_dtime_high;
>      __time_t shm_dtime;                        /* time of last shmdt() */
> -    unsigned long int __glibc_reserved3;
> +    unsigned long int __shm_ctime_high;
>      __time_t shm_ctime;                        /* time of last change by shmctl() */
>      unsigned long int __glibc_reserved4;
>  #else
> diff --git a/sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h b/sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h
> new file mode 100644
> index 0000000000..5533d44dee
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h
> @@ -0,0 +1,24 @@
> +/* Analogous to kernel struct shmid64_ds used on shmctl.  */
> +struct kernel_shmid64_ds
> +{
> +  struct ipc_perm shm_perm;
> +#if __TIMESIZE == 64
> +  long int shm_atime;
> +  long int shm_atime;
> +  long int shm_atime;

This fails to compile as all three variables have the same name.

Alistair
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 7/7] sysv: linux: Add 64-bit time_t variant for shmctl

Sourceware - libc-alpha mailing list


On 30/06/2020 23:28, Alistair Francis wrote:
deps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h b/sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h

>> new file mode 100644
>> index 0000000000..5533d44dee
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h
>> @@ -0,0 +1,24 @@
>> +/* Analogous to kernel struct shmid64_ds used on shmctl.  */
>> +struct kernel_shmid64_ds
>> +{
>> +  struct ipc_perm shm_perm;
>> +#if __TIMESIZE == 64
>> +  long int shm_atime;
>> +  long int shm_atime;
>> +  long int shm_atime;
>
> This fails to compile as all three variables have the same name.

In fact this code specifically is not used on powerpc since it will
either use the __TIMESIZE == 32 (powerpc32) or not use this
structure at all (powerpc64{le}).  But it is still an issue I will
revise the patch for such issues and remove it (maybe adding a
#error if it used on powerpc64).

Besides it, does it work for riscv32 (which should use the default
definition)?
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 7/7] sysv: linux: Add 64-bit time_t variant for shmctl

Sourceware - libc-alpha mailing list
On Wed, Jul 1, 2020 at 5:19 AM Adhemerval Zanella
<[hidden email]> wrote:

>
>
>
> On 30/06/2020 23:28, Alistair Francis wrote:
> deps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h b/sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h
> >> new file mode 100644
> >> index 0000000000..5533d44dee
> >> --- /dev/null
> >> +++ b/sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h
> >> @@ -0,0 +1,24 @@
> >> +/* Analogous to kernel struct shmid64_ds used on shmctl.  */
> >> +struct kernel_shmid64_ds
> >> +{
> >> +  struct ipc_perm shm_perm;
> >> +#if __TIMESIZE == 64
> >> +  long int shm_atime;
> >> +  long int shm_atime;
> >> +  long int shm_atime;
> >
> > This fails to compile as all three variables have the same name.
>
> In fact this code specifically is not used on powerpc since it will
> either use the __TIMESIZE == 32 (powerpc32) or not use this
> structure at all (powerpc64{le}).  But it is still an issue I will
> revise the patch for such issues and remove it (maybe adding a
> #error if it used on powerpc64).

Ah whoops, I commented inline on the wrong file. The generic one
(sysdeps/unix/sysv/linux/struct_kernel_shmid64_ds.h) also has the same
problem which is why I saw the RISC-V build fail.

>
> Besides it, does it work for riscv32 (which should use the default
> definition)?

This patch doesn't work due to the same name variables in a few places
(one of them being the generic one).

I am testing all the other patches and should know by tonight (about 8
hours still), I'll let you know.

Alistair
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 7/7] sysv: linux: Add 64-bit time_t variant for shmctl

Sourceware - libc-alpha mailing list


On 01/07/2020 12:48, Alistair Francis wrote:

> On Wed, Jul 1, 2020 at 5:19 AM Adhemerval Zanella
> <[hidden email]> wrote:
>>
>>
>>
>> On 30/06/2020 23:28, Alistair Francis wrote:
>> deps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h b/sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h
>>>> new file mode 100644
>>>> index 0000000000..5533d44dee
>>>> --- /dev/null
>>>> +++ b/sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h
>>>> @@ -0,0 +1,24 @@
>>>> +/* Analogous to kernel struct shmid64_ds used on shmctl.  */
>>>> +struct kernel_shmid64_ds
>>>> +{
>>>> +  struct ipc_perm shm_perm;
>>>> +#if __TIMESIZE == 64
>>>> +  long int shm_atime;
>>>> +  long int shm_atime;
>>>> +  long int shm_atime;
>>>
>>> This fails to compile as all three variables have the same name.
>>
>> In fact this code specifically is not used on powerpc since it will
>> either use the __TIMESIZE == 32 (powerpc32) or not use this
>> structure at all (powerpc64{le}).  But it is still an issue I will
>> revise the patch for such issues and remove it (maybe adding a
>> #error if it used on powerpc64).
>
> Ah whoops, I commented inline on the wrong file. The generic one
> (sysdeps/unix/sysv/linux/struct_kernel_shmid64_ds.h) also has the same
> problem which is why I saw the RISC-V build fail.
>
>>
>> Besides it, does it work for riscv32 (which should use the default
>> definition)?
>
> This patch doesn't work due to the same name variables in a few places
> (one of them being the generic one).
>

I need to setup an 32-bit ABI with 64-bit time_t to catch these kind of
issues.  

> I am testing all the other patches and should know by tonight (about 8
> hours still), I'll let you know.

Ack, you can also do a sniff test with the sysvipc tests to check if
they are ok.

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 7/7] sysv: linux: Add 64-bit time_t variant for shmctl

Sourceware - libc-alpha mailing list


On 01/07/2020 13:35, Adhemerval Zanella wrote:

>
>
> On 01/07/2020 12:48, Alistair Francis wrote:
>> On Wed, Jul 1, 2020 at 5:19 AM Adhemerval Zanella
>> <[hidden email]> wrote:
>>>
>>>
>>>
>>> On 30/06/2020 23:28, Alistair Francis wrote:
>>> deps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h b/sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h
>>>>> new file mode 100644
>>>>> index 0000000000..5533d44dee
>>>>> --- /dev/null
>>>>> +++ b/sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h
>>>>> @@ -0,0 +1,24 @@
>>>>> +/* Analogous to kernel struct shmid64_ds used on shmctl.  */
>>>>> +struct kernel_shmid64_ds
>>>>> +{
>>>>> +  struct ipc_perm shm_perm;
>>>>> +#if __TIMESIZE == 64
>>>>> +  long int shm_atime;
>>>>> +  long int shm_atime;
>>>>> +  long int shm_atime;
>>>>
>>>> This fails to compile as all three variables have the same name.
>>>
>>> In fact this code specifically is not used on powerpc since it will
>>> either use the __TIMESIZE == 32 (powerpc32) or not use this
>>> structure at all (powerpc64{le}).  But it is still an issue I will
>>> revise the patch for such issues and remove it (maybe adding a
>>> #error if it used on powerpc64).
>>
>> Ah whoops, I commented inline on the wrong file. The generic one
>> (sysdeps/unix/sysv/linux/struct_kernel_shmid64_ds.h) also has the same
>> problem which is why I saw the RISC-V build fail.
>>
>>>
>>> Besides it, does it work for riscv32 (which should use the default
>>> definition)?
>>
>> This patch doesn't work due to the same name variables in a few places
>> (one of them being the generic one).
>>
>
> I need to setup an 32-bit ABI with 64-bit time_t to catch these kind of
> issues.  
>
>> I am testing all the other patches and should know by tonight (about 8
>> hours still), I'll let you know.
>
> Ack, you can also do a sniff test with the sysvipc tests to check if
> they are ok.

Ok, the __TIMESIZE should not be used to define the kernel_* struct anyway,
they should be independent of the glibc time ABI selected or defined by
the ABI.

I have updated my personal branch [1] with an updated version and I will
try to check if riscv32 at least built against. If you could also check
it would be helpful.

[1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/semctl-y2038
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 7/7] sysv: linux: Add 64-bit time_t variant for shmctl

Sourceware - libc-alpha mailing list
On 7/1/20 10:07 AM, Adhemerval Zanella via Libc-alpha wrote:

>> Ack, you can also do a sniff test with the sysvipc tests to check if
>> they are ok.
>
> Ok, the __TIMESIZE should not be used to define the kernel_* struct anyway,
> they should be independent of the glibc time ABI selected or defined by
> the ABI.
>
> I have updated my personal branch [1] with an updated version and I will
> try to check if riscv32 at least built against. If you could also check
> it would be helpful.
>
> [1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/semctl-y2038

I've rebased ARC port on this (dropped the prior versions from rv32) and these
seem to work !

| PASS: sysvipc/check-installed-headers-c
| PASS: sysvipc/check-installed-headers-cxx
| PASS: sysvipc/check-obsolete-constructs
| PASS: sysvipc/check-wrapper-headers
| PASS: sysvipc/test-sysvmsg
| PASS: sysvipc/test-sysvsem
| PASS: sysvipc/test-sysvshm

FWIW: Tested-by: Vineet Gupta <[hidden email]>


Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 7/7] sysv: linux: Add 64-bit time_t variant for shmctl

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
On Wed, Jul 1, 2020 at 10:07 AM Adhemerval Zanella
<[hidden email]> wrote:

>
>
>
> On 01/07/2020 13:35, Adhemerval Zanella wrote:
> >
> >
> > On 01/07/2020 12:48, Alistair Francis wrote:
> >> On Wed, Jul 1, 2020 at 5:19 AM Adhemerval Zanella
> >> <[hidden email]> wrote:
> >>>
> >>>
> >>>
> >>> On 30/06/2020 23:28, Alistair Francis wrote:
> >>> deps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h b/sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h
> >>>>> new file mode 100644
> >>>>> index 0000000000..5533d44dee
> >>>>> --- /dev/null
> >>>>> +++ b/sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h
> >>>>> @@ -0,0 +1,24 @@
> >>>>> +/* Analogous to kernel struct shmid64_ds used on shmctl.  */
> >>>>> +struct kernel_shmid64_ds
> >>>>> +{
> >>>>> +  struct ipc_perm shm_perm;
> >>>>> +#if __TIMESIZE == 64
> >>>>> +  long int shm_atime;
> >>>>> +  long int shm_atime;
> >>>>> +  long int shm_atime;
> >>>>
> >>>> This fails to compile as all three variables have the same name.
> >>>
> >>> In fact this code specifically is not used on powerpc since it will
> >>> either use the __TIMESIZE == 32 (powerpc32) or not use this
> >>> structure at all (powerpc64{le}).  But it is still an issue I will
> >>> revise the patch for such issues and remove it (maybe adding a
> >>> #error if it used on powerpc64).
> >>
> >> Ah whoops, I commented inline on the wrong file. The generic one
> >> (sysdeps/unix/sysv/linux/struct_kernel_shmid64_ds.h) also has the same
> >> problem which is why I saw the RISC-V build fail.
> >>
> >>>
> >>> Besides it, does it work for riscv32 (which should use the default
> >>> definition)?
> >>
> >> This patch doesn't work due to the same name variables in a few places
> >> (one of them being the generic one).
> >>
> >
> > I need to setup an 32-bit ABI with 64-bit time_t to catch these kind of
> > issues.
> >
> >> I am testing all the other patches and should know by tonight (about 8
> >> hours still), I'll let you know.
> >
> > Ack, you can also do a sniff test with the sysvipc tests to check if
> > they are ok.
>
> Ok, the __TIMESIZE should not be used to define the kernel_* struct anyway,
> they should be independent of the glibc time ABI selected or defined by
> the ABI.
>
> I have updated my personal branch [1] with an updated version and I will
> try to check if riscv32 at least built against. If you could also check
> it would be helpful.

Thanks!

I have tested this series with patch 7 (this patch) dropped and it
works for RV32.

>
> [1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/semctl-y2038

I am now running a full test of this branch, unfortunately it'll take
about 24 hours.

Alistair
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 1/7] sysv: linux: Add 64-bit time_t variant for semctl

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
On Tue, Jun 30, 2020 at 12:26 PM Adhemerval Zanella via Libc-alpha
<[hidden email]> wrote:

>
> Different than others 64-bit time_t syscalls, the SysIPC interface
> does not provide a new set of syscall for y2038 safeness.  Instead it
> uses ununsed fields in semid_ds structure the return the high bits for
> the timestamps.
>
> To provide a y2038 safe interface a new symbol __semctl64 is added
> and __semctl is change to call it instead (it adds some extra buffer
> copy for the 32 bit time_t implementation).
>
> Two two new structures are added:
>
>   1. kernel_semid64_ds: used internally only on 32-bit architectures
>      to issue the syscall.  A handful architectures (hppa, i386, mips,
>      powerpc32, sparc32) requires specific implementation due its
>      specific kernel ABI.
>
>   2. semid_ds64: this is only for __TIMESIZE != 64 to use along with
>      the 64-bit semctl.  It is different than the kernel one because
>      the exported 64-bit time_t might require different alignment
>      depending of the architecture ABI.
>
> So the resulting implementation does:
>
>   1. For 64-bit architectures it assumes semid_ds already contains
>      64-bit time_t fields it will result in just the __semctl symbol
>      using the __semctl64 code.  The semid_ds argument is passed as-is
>      to the syscall.
>
>   2. For 32-bit architectures with default 64-bit time_t (newer ABIs
>      such riscv32 or arc), it will also result in only one exported
>      symbol but with the required high/low handling.
>
>      It might be possible to optimize it further to avoid the
>      kernel_semid64_ds to semun transformation if the exported ABI
>      for the architectures matches the expected kernel ABI, but the
>      implementation is already complex enough and don't think this
>      should be a hotspot in any case.
>
>   3. Finally for 32-bit architecture with both 32-bit and 64-bit time_t
>      support we follow the already set way to provide one symbol with
>      64-bit time_t support and implement the 32-bit time_t support on
>      basis of the 64-bit one.
>
>      The default 32-bit symbol will allocate and copy the semid_ds
>      over multiple buffers, but this should be deprecated in favor
>      of the __semctl64 anyway.
>
> Checked on i686-linux-gnu and x86_64-linux-gnu.  I also did some sniff
> tests on powerpc, powerpc64, mips, mips64, armhf, sparcv9, and
> sparc64.

This looks good.

Reviewed-by: Alistair Francis <[hidden email]>

Alistair

> ---
>  include/sys/sem.h                             |   7 +
>  .../sysv/linux/bits/types/struct_semid64_ds.h |  33 +++
>  .../sysv/linux/bits/types/struct_semid_ds.h   |  21 +-
>  .../linux/hppa/bits/types/struct_semid_ds.h   |   6 +-
>  .../linux/hppa/struct_kernel_semid64_ds.h     |  12 +
>  .../linux/i386/struct_kernel_semid64_ds.h     |  12 +
>  sysdeps/unix/sysv/linux/ipc_priv.h            |  10 +
>  .../linux/mips/bits/types/struct_semid_ds.h   |   4 +-
>  .../linux/mips/struct_kernel_semid64_ds.h     |  10 +
>  .../powerpc/bits/types/struct_semid_ds.h      |   4 +-
>  .../powerpc32/struct_kernel_semid64_ds.h      |  12 +
>  sysdeps/unix/sysv/linux/semctl.c              | 261 +++++++++++++++---
>  .../linux/sparc/bits/types/struct_semid_ds.h  |   4 +-
>  .../sparc/sparc32/struct_kernel_semid64_ds.h  |  12 +
>  .../sysv/linux/struct_kernel_semid64_ds.h     |  12 +
>  .../linux/x86/bits/types/struct_semid_ds.h    |   4 +-
>  16 files changed, 359 insertions(+), 65 deletions(-)
>  create mode 100644 sysdeps/unix/sysv/linux/bits/types/struct_semid64_ds.h
>  create mode 100644 sysdeps/unix/sysv/linux/hppa/struct_kernel_semid64_ds.h
>  create mode 100644 sysdeps/unix/sysv/linux/i386/struct_kernel_semid64_ds.h
>  create mode 100644 sysdeps/unix/sysv/linux/mips/struct_kernel_semid64_ds.h
>  create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/struct_kernel_semid64_ds.h
>  create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/struct_kernel_semid64_ds.h
>  create mode 100644 sysdeps/unix/sysv/linux/struct_kernel_semid64_ds.h
>
> diff --git a/include/sys/sem.h b/include/sys/sem.h
> index 69fdf1f752..a9151e057d 100644
> --- a/include/sys/sem.h
> +++ b/include/sys/sem.h
> @@ -5,5 +5,12 @@
>
>  __typeof__ (semtimedop) __semtimedop attribute_hidden;
>
> +#if __TIMESIZE == 64
> +# define __semctl64 __semctl
> +#else
> +extern int __semctl64 (int semid, int semnum, int cmd, ...);
> +libc_hidden_proto (__semctl64);
> +#endif
> +
>  # endif
>  #endif
> diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_semid64_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_semid64_ds.h
> new file mode 100644
> index 0000000000..bda9eb4469
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/bits/types/struct_semid64_ds.h
> @@ -0,0 +1,33 @@
> +/* Generic implementation of the semaphore struct semid64_ds.
> +   Copyright (C) 2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _SYS_SEM_H
> +# error "Never include <bits/types/struct_semid_ds.h> directly; use <sys/sem.h> instead."
> +#endif
> +
> +#if __TIMESIZE == 64
> +# define __semid64_ds semid_ds
> +#else
> +struct __semid64_ds
> +{
> +  struct ipc_perm sem_perm;            /* operation permission struct */
> +  __time64_t sem_otime;                        /* last semop() time */
> +  __time64_t sem_ctime;                        /* last time changed by semctl() */
> +  __syscall_ulong_t sem_nsems;         /* number of semaphores in set */
> +};
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_semid_ds.h
> index 4222e6a59f..bc26d8be08 100644
> --- a/sysdeps/unix/sysv/linux/bits/types/struct_semid_ds.h
> +++ b/sysdeps/unix/sysv/linux/bits/types/struct_semid_ds.h
> @@ -21,26 +21,19 @@
>  #endif
>
>  /* Data structure describing a set of semaphores.  */
> -#if __TIMESIZE == 32
>  struct semid_ds
>  {
>    struct ipc_perm sem_perm;        /* operation permission struct */
> +#if __TIMESIZE == 32
>    __time_t sem_otime;              /* last semop() time */
> -  __syscall_ulong_t __glibc_reserved1;
> +  __syscall_ulong_t __sem_otime_high;
>    __time_t sem_ctime;             /* last time changed by semctl() */
> -  __syscall_ulong_t __glibc_reserved2;
> -  __syscall_ulong_t sem_nsems;    /* number of semaphores in set */
> -  __syscall_ulong_t __glibc_reserved3;
> -  __syscall_ulong_t __glibc_reserved4;
> -};
> +  __syscall_ulong_t __sem_ctime_high;
>  #else
> -struct semid_ds
> -{
> -  struct ipc_perm sem_perm;            /* operation permission struct */
> -  __time_t sem_otime;                  /* last semop() time */
> -  __time_t sem_ctime;                  /* last time changed by semctl() */
> -  __syscall_ulong_t sem_nsems;         /* number of semaphores in set */
> +  __time_t sem_otime;
> +  __time_t sem_ctime;
> +#endif
> +  __syscall_ulong_t sem_nsems;    /* number of semaphores in set */
>    __syscall_ulong_t __glibc_reserved3;
>    __syscall_ulong_t __glibc_reserved4;
>  };
> -#endif
> diff --git a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_semid_ds.h
> index d4c50b5ef8..68f9eca24c 100644
> --- a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_semid_ds.h
> +++ b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_semid_ds.h
> @@ -21,16 +21,14 @@
>  #endif
>
>  /* Data structure describing a set of semaphores.  */
> -#if __TIMESIZE == 32
>  struct semid_ds
>  {
>    struct ipc_perm sem_perm;   /* operation permission struct */
> -  __syscall_ulong_t __glibc_reserved1;
> +  __syscall_ulong_t __sem_otime_high;
>    __time_t sem_otime;         /* last semop() time */
> -  __syscall_ulong_t __glibc_reserved2;
> +  __syscall_ulong_t __sem_ctime_high;
>    __time_t sem_ctime;         /* last time changed by semctl() */
>    __syscall_ulong_t sem_nsems;    /* number of semaphores in set */
>    __syscall_ulong_t __glibc_reserved3;
>    __syscall_ulong_t __glibc_reserved4;
>  };
> -#endif
> diff --git a/sysdeps/unix/sysv/linux/hppa/struct_kernel_semid64_ds.h b/sysdeps/unix/sysv/linux/hppa/struct_kernel_semid64_ds.h
> new file mode 100644
> index 0000000000..2871030d0d
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/hppa/struct_kernel_semid64_ds.h
> @@ -0,0 +1,12 @@
> +/* Analogous to kernel struct semid64_ds used on semctl.  */
> +struct kernel_semid64_ds
> +{
> +  struct ipc_perm sem_perm;
> +  unsigned long sem_otime_high;
> +  unsigned long sem_otime;
> +  unsigned long sem_ctime_high;
> +  unsigned long sem_ctime;
> +  unsigned long sem_nsems;
> +  unsigned long __ununsed1;
> +  unsigned long __ununsed2;
> +};
> diff --git a/sysdeps/unix/sysv/linux/i386/struct_kernel_semid64_ds.h b/sysdeps/unix/sysv/linux/i386/struct_kernel_semid64_ds.h
> new file mode 100644
> index 0000000000..bab9cf63ba
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/i386/struct_kernel_semid64_ds.h
> @@ -0,0 +1,12 @@
> +/* Analogous to kernel struct semid64_ds used on semctl.  */
> +struct kernel_semid64_ds
> +{
> +  struct ipc_perm sem_perm;
> +  unsigned long sem_otime;
> +  unsigned long sem_otime_high;
> +  unsigned long sem_ctime;
> +  unsigned long sem_ctime_high;
> +  __syscall_ulong_t sem_nsems;
> +  __syscall_ulong_t __unused3;
> +  __syscall_ulong_t __unused4;
> +};
> diff --git a/sysdeps/unix/sysv/linux/ipc_priv.h b/sysdeps/unix/sysv/linux/ipc_priv.h
> index 15a6e683a4..93a6e5cb24 100644
> --- a/sysdeps/unix/sysv/linux/ipc_priv.h
> +++ b/sysdeps/unix/sysv/linux/ipc_priv.h
> @@ -53,4 +53,14 @@ struct __old_ipc_perm
>  #define SEMTIMEDOP_IPC_ARGS(__nsops, __sops, __timeout) \
>    (__nsops), 0, (__sops), (__timeout)
>
> +/* Linux SysV ipc does not provide new syscalls for 64-bit time support on
> +   32-bit architectures, but rather split the timestamps on previous unused
> +   fields.  */
> +#if (__WORDSIZE == 32 \
> +     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
> +# define __IPC_TIME64 1
> +#else
> +# define __IPC_TIME64 0
> +#endif
> +
>  #include <ipc_ops.h>
> diff --git a/sysdeps/unix/sysv/linux/mips/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/mips/bits/types/struct_semid_ds.h
> index 8954209a29..eec4a18cae 100644
> --- a/sysdeps/unix/sysv/linux/mips/bits/types/struct_semid_ds.h
> +++ b/sysdeps/unix/sysv/linux/mips/bits/types/struct_semid_ds.h
> @@ -27,6 +27,6 @@ struct semid_ds
>    __time_t sem_otime;  /* last semop() time */
>    __time_t sem_ctime;  /* last time changed by semctl() */
>    __syscall_ulong_t sem_nsems;         /* number of semaphores in set */
> -  __syscall_ulong_t __glibc_reserved3;
> -  __syscall_ulong_t __glibc_reserved4;
> +  __syscall_ulong_t __sem_otime_high;
> +  __syscall_ulong_t __sem_ctime_high;
>  };
> diff --git a/sysdeps/unix/sysv/linux/mips/struct_kernel_semid64_ds.h b/sysdeps/unix/sysv/linux/mips/struct_kernel_semid64_ds.h
> new file mode 100644
> index 0000000000..76a9d83ea5
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/mips/struct_kernel_semid64_ds.h
> @@ -0,0 +1,10 @@
> +/* Analogous to kernel struct semid64_ds used on semctl.  */
> +struct kernel_semid64_ds
> +{
> +  struct ipc_perm sem_perm;
> +  unsigned long sem_otime;
> +  unsigned long sem_ctime;
> +  unsigned long sem_nsems;
> +  unsigned long sem_otime_high;
> +  unsigned long sem_ctime_high;
> +};
> diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_semid_ds.h
> index 300a9b98e9..d382d93c52 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_semid_ds.h
> +++ b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_semid_ds.h
> @@ -25,9 +25,9 @@ struct semid_ds
>  {
>    struct ipc_perm sem_perm;   /* operation permission struct */
>  #if __TIMESIZE == 32
> -  __syscall_ulong_t __glibc_reserved1;
> +  __syscall_ulong_t __sem_otime_high;
>    __time_t sem_otime;         /* last semop() time */
> -  __syscall_ulong_t __glibc_reserved2;
> +  __syscall_ulong_t __sem_ctime_high;
>    __time_t sem_ctime;        /* last time changed by semctl() */
>  #else
>    __time_t sem_otime;         /* last semop() time */
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/struct_kernel_semid64_ds.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/struct_kernel_semid64_ds.h
> new file mode 100644
> index 0000000000..7fa4ef6424
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/struct_kernel_semid64_ds.h
> @@ -0,0 +1,12 @@
> +/* Analogous to kernel struct semid64_ds used on semctl.  */
> +struct kernel_semid64_ds
> +{
> +  struct ipc_perm sem_perm;
> +  unsigned long sem_otime_high;
> +  unsigned long sem_otime;
> +  unsigned long sem_ctime_high;
> +  unsigned long sem_ctime;
> +  unsigned long sem_nsems;
> +  unsigned long __unused3;
> +  unsigned long __unused4;
> +};
> diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c
> index 30571af49f..3a06270242 100644
> --- a/sysdeps/unix/sysv/linux/semctl.c
> +++ b/sysdeps/unix/sysv/linux/semctl.c
> @@ -21,10 +21,13 @@
>  #include <ipc_priv.h>
>  #include <sysdep.h>
>  #include <shlib-compat.h>
> -#include <errno.h>
> -#include <linux/posix_types.h>  /* For __kernel_mode_t.  */
> +#include <bits/types/struct_semid64_ds.h>  /* For __semid64_ds.  */
> +#include <linux/posix_types.h>             /* For __kernel_mode_t.  */
>
> -/* Define a `union semun' suitable for Linux here.  */
> +/* The struct used to issue the syscall.  For architecture that assume
> +   64-bit time as default (!__ASSUME_TIME64_SYSCALLS) the syscall will
> +   split the resulting 64-bit sem_{o,c}time in two fields (__sem_{o,c}time
> +   and __sem_{o,c}time_hi).  */
>  union semun
>  {
>    int val;                     /* value for SETVAL */
> @@ -33,16 +36,89 @@ union semun
>    struct seminfo *__buf;       /* buffer for IPC_INFO */
>  };
>
> -#ifndef DEFAULT_VERSION
> -# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T
> -#  define DEFAULT_VERSION GLIBC_2_2
> +#if __IPC_TIME64 == 0
> +# define semun64 semun
> +typedef union semun semctl_arg_t;
> +#else
> +# include <struct_kernel_semid64_ds.h>
> +
> +union ksemun64
> +{
> +  int val;
> +  struct kernel_semid64_ds *buf;
> +  unsigned short int *array;
> +  struct seminfo *__buf;
> +};
> +
> +# if __TIMESIZE == 64
> +#  define semun64 semun
>  # else
> -#  define DEFAULT_VERSION GLIBC_2_31
> +/* The struct used when __semctl64 is called.  */
> +union semun64
> +{
> +  int val;
> +  struct __semid64_ds *buf;
> +  unsigned short int *array;
> +  struct seminfo *__buf;
> +};
>  # endif
> +
> +static void
> +semid64_to_ksemid64 (const struct __semid64_ds *semid64,
> +                    struct kernel_semid64_ds *ksemid)
> +{
> +  ksemid->sem_perm       = semid64->sem_perm;
> +  ksemid->sem_otime      = semid64->sem_otime;
> +  ksemid->sem_otime_high = semid64->sem_otime >> 32;
> +  ksemid->sem_ctime      = semid64->sem_ctime;
> +  ksemid->sem_ctime_high = semid64->sem_ctime >> 32;
> +  ksemid->sem_nsems      = semid64->sem_nsems;
> +}
> +
> +static void
> +ksemid64_to_semid64 (const struct kernel_semid64_ds *ksemid,
> +                    struct __semid64_ds *semid64)
> +{
> +  semid64->sem_perm  = ksemid->sem_perm;
> +  semid64->sem_otime = ksemid->sem_otime
> +                      | ((__time64_t) ksemid->sem_otime_high << 32);
> +  semid64->sem_ctime = ksemid->sem_ctime
> +                      | ((__time64_t) ksemid->sem_ctime_high << 32);
> +  semid64->sem_nsems = ksemid->sem_nsems;
> +}
> +
> +static union ksemun64
> +semun64_to_ksemun64 (int cmd, union semun64 semun64,
> +                    struct kernel_semid64_ds *buf)
> +{
> +  union ksemun64 r = { 0 };
> +  switch (cmd)
> +    {
> +    case SETVAL:
> +      r.val = semun64.val;
> +      break;
> +    case GETALL:
> +    case SETALL:
> +      r.array = semun64.array;
> +      break;
> +    case IPC_STAT:
> +    case IPC_SET:
> +      r.buf = buf;
> +      semid64_to_ksemid64 (semun64.buf, r.buf);
> +      break;
> +    case IPC_INFO:
> +    case SEM_INFO:
> +      r.__buf = semun64.__buf;
> +      break;
> +    }
> +  return r;
> +}
> +
> +typedef union ksemun64 semctl_arg_t;
>  #endif
>
>  static int
> -semctl_syscall (int semid, int semnum, int cmd, union semun arg)
> +semctl_syscall (int semid, int semnum, int cmd, semctl_arg_t arg)
>  {
>  #ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
>    return INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd | __IPC_64,
> @@ -53,15 +129,15 @@ semctl_syscall (int semid, int semnum, int cmd, union semun arg)
>  #endif
>  }
>
> +/* POSIX states ipc_perm mode should have type of mode_t.  */
> +_Static_assert (sizeof ((struct semid_ds){0}.sem_perm.mode)
> +               == sizeof (mode_t),
> +               "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)");
> +
>  int
> -__new_semctl (int semid, int semnum, int cmd, ...)
> +__semctl64 (int semid, int semnum, int cmd, ...)
>  {
> -  /* POSIX states ipc_perm mode should have type of mode_t.  */
> -  _Static_assert (sizeof ((struct semid_ds){0}.sem_perm.mode)
> -                 == sizeof (mode_t),
> -                 "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)");
> -
> -  union semun arg = { 0 };
> +  union semun64 arg64 = { 0 };
>    va_list ap;
>
>    /* Get the argument only if required.  */
> @@ -76,44 +152,151 @@ __new_semctl (int semid, int semnum, int cmd, ...)
>      case IPC_INFO:      /* arg.__buf */
>      case SEM_INFO:
>        va_start (ap, cmd);
> -      arg = va_arg (ap, union semun);
> +      arg64 = va_arg (ap, union semun64);
>        va_end (ap);
>        break;
>      }
>
> -#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
> -  struct semid_ds tmpds;
> -  if (cmd == IPC_SET)
> -    {
> -      tmpds = *arg.buf;
> -      tmpds.sem_perm.mode *= 0x10000U;
> -      arg.buf = &tmpds;
> -    }
> +#if __IPC_TIME64
> +  struct kernel_semid64_ds ksemid;
> +  union ksemun64 ksemun = semun64_to_ksemun64 (cmd, arg64, &ksemid);
> +  union ksemun64 arg = ksemun;
> +#else
> +  union semun arg = arg64;
>  #endif
>
>    int ret = semctl_syscall (semid, semnum, cmd, arg);
> +  if (ret < 0)
> +    return ret;
>
> -  if (ret >= 0)
> +  switch (cmd)
>      {
> -      switch (cmd)
> -       {
> -        case IPC_STAT:
> -        case SEM_STAT:
> -        case SEM_STAT_ANY:
> +    case IPC_STAT:
> +    case SEM_STAT:
> +    case SEM_STAT_ANY:
>  #ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
> -          arg.buf->sem_perm.mode >>= 16;
> +      arg.buf->sem_perm.mode >>= 16;
>  #else
> -         /* Old Linux kernel versions might not clear the mode padding.  */
> -         if (sizeof ((struct semid_ds){0}.sem_perm.mode)
> -             != sizeof (__kernel_mode_t))
> -           arg.buf->sem_perm.mode &= 0xFFFF;
> +      /* Old Linux kernel versions might not clear the mode padding.  */
> +      if (sizeof ((struct semid_ds){0}.sem_perm.mode)
> +         != sizeof (__kernel_mode_t))
> +       arg.buf->sem_perm.mode &= 0xFFFF;
>  #endif
> -       }
> +
> +#if __IPC_TIME64
> +      ksemid64_to_semid64 (arg.buf, arg64.buf);
> +#endif
> +    }
> +
> +  return ret;
> +}
> +#if __TIMESIZE != 64
> +libc_hidden_def (__semctl64)
> +
> +
> +/* The 64-bit time_t semid_ds version might have a different layout and
> +   internal field alignment.  */
> +static void
> +semid64_ds_to_semid_ds (struct semid_ds *ds, const struct __semid64_ds *ds64)
> +{
> +  ds->sem_perm = ds64->sem_perm;
> +  ds->sem_otime = ds64->sem_otime;
> +  ds->sem_ctime = ds64->sem_ctime;
> +  ds->sem_nsems = ds64->sem_nsems;
> +}
> +
> +static void
> +semid_ds_to_semid64_ds (struct __semid64_ds *ds64, const struct semid_ds *ds)
> +{
> +  ds64->sem_perm = ds->sem_perm;
> +  ds64->sem_otime = ds->sem_otime
> +                   | ((__time64_t) ds->__sem_otime_high << 32);
> +  ds64->sem_ctime = ds->sem_ctime
> +                   | ((__time64_t) ds->__sem_ctime_high << 32);
> +  ds64->sem_nsems = ds->sem_nsems;
> +}
> +
> +static union semun64
> +semun_to_semun64 (int cmd, union semun semun, struct __semid64_ds *semid64)
> +{
> +  union semun64 r = { 0 };
> +  switch (cmd)
> +    {
> +    case SETVAL:
> +      r.val = semun.val;
> +      break;
> +    case GETALL:
> +    case SETALL:
> +      r.array = semun.array;
> +      break;
> +    case IPC_STAT:
> +    case IPC_SET:
> +      r.buf = semid64;
> +      semid_ds_to_semid64_ds (r.buf, semun.buf);
> +# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
> +      if (cmd == IPC_SET)
> +       r.buf->sem_perm.mode *= 0x10000U;
> +# endif
> +      break;
> +    case IPC_INFO:
> +    case SEM_INFO:
> +      r.__buf = semun.__buf;
> +      break;
> +    }
> +  return r;
> +}
> +
> +int
> +__semctl (int semid, int semnum, int cmd, ...)
> +{
> +  union semun arg = { 0 };
> +
> +  va_list ap;
> +
> +  /* Get the argument only if required.  */
> +  switch (cmd)
> +    {
> +    case SETVAL:        /* arg.val */
> +    case GETALL:        /* arg.array */
> +    case SETALL:
> +    case IPC_STAT:      /* arg.buf */
> +    case IPC_SET:
> +    case SEM_STAT:
> +    case IPC_INFO:      /* arg.__buf */
> +    case SEM_INFO:
> +      va_start (ap, cmd);
> +      arg = va_arg (ap, union semun);
> +      va_end (ap);
> +      break;
> +    }
> +
> +  struct __semid64_ds semid64;
> +  union semun64 arg64 = semun_to_semun64 (cmd, arg, &semid64);
> +
> +  int ret = __semctl64 (semid, semnum, cmd, arg64);
> +  if (ret < 0)
> +    return ret;
> +
> +  switch (cmd)
> +    {
> +    case IPC_STAT:
> +    case SEM_STAT:
> +    case SEM_STAT_ANY:
> +      semid64_ds_to_semid_ds (arg.buf, arg64.buf);
>      }
>
>    return ret;
>  }
> -versioned_symbol (libc, __new_semctl, semctl, DEFAULT_VERSION);
> +#endif
> +
> +#ifndef DEFAULT_VERSION
> +# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T
> +#  define DEFAULT_VERSION GLIBC_2_2
> +# else
> +#  define DEFAULT_VERSION GLIBC_2_31
> +# endif
> +#endif
> +versioned_symbol (libc, __semctl, semctl, DEFAULT_VERSION);
>
>  #if defined __ASSUME_SYSVIPC_BROKEN_MODE_T \
>      && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_31)
> @@ -121,7 +304,7 @@ int
>  attribute_compat_text_section
>  __semctl_mode16 (int semid, int semnum, int cmd, ...)
>  {
> -  union semun arg = { 0 };
> +  semctl_arg_t arg = { 0 };
>    va_list ap;
>
>    /* Get the argument only if required.  */
> @@ -136,7 +319,7 @@ __semctl_mode16 (int semid, int semnum, int cmd, ...)
>      case IPC_INFO:      /* arg.__buf */
>      case SEM_INFO:
>        va_start (ap, cmd);
> -      arg = va_arg (ap, union semun);
> +      arg = va_arg (ap, semctl_arg_t);
>        va_end (ap);
>        break;
>      }
> diff --git a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_semid_ds.h
> index 46fcd79fb6..0110c1a940 100644
> --- a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_semid_ds.h
> +++ b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_semid_ds.h
> @@ -25,9 +25,9 @@ struct semid_ds
>  {
>    struct ipc_perm sem_perm;   /* operation permission struct */
>  #if __TIMESIZE == 32
> -  __syscall_ulong_t __glibc_reserved1;
> +  __syscall_ulong_t __sem_otime_high;
>    __time_t sem_otime;         /* last semop() time */
> -  __syscall_ulong_t __glibc_reserved2;
> +  __syscall_ulong_t __sem_ctime_high;
>    __time_t sem_ctime;        /* last time changed by semctl() */
>  #else
>    __time_t sem_otime;         /* last semop() time */
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/struct_kernel_semid64_ds.h b/sysdeps/unix/sysv/linux/sparc/sparc32/struct_kernel_semid64_ds.h
> new file mode 100644
> index 0000000000..8c4697f9ab
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/struct_kernel_semid64_ds.h
> @@ -0,0 +1,12 @@
> +/* Analogous to kernel struct semid64_ds used on semctl.  */
> +struct kernel_semid64_ds
> +{
> +  struct ipc_perm sem_perm;
> +  unsigned long sem_otime_high;
> +  unsigned long sem_otime;
> +  unsigned long sem_ctime_high;
> +  unsigned long sem_ctime;
> +  unsigned long sem_nsems;
> +  unsigned long __unused1;
> +  unsigned long __unused2;
> +};
> diff --git a/sysdeps/unix/sysv/linux/struct_kernel_semid64_ds.h b/sysdeps/unix/sysv/linux/struct_kernel_semid64_ds.h
> new file mode 100644
> index 0000000000..f9edf0f76f
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/struct_kernel_semid64_ds.h
> @@ -0,0 +1,12 @@
> +/* Analogous to kernel struct semid64_ds used on semctl.  */
> +struct kernel_semid64_ds
> +{
> +  struct ipc_perm sem_perm;
> +  unsigned long sem_otime;
> +  unsigned long sem_otime_high;
> +  unsigned long sem_ctime;
> +  unsigned long sem_ctime_high;
> +  unsigned long sem_nsems;
> +  unsigned long __unused1;
> +  unsigned long __unused2;
> +};
> diff --git a/sysdeps/unix/sysv/linux/x86/bits/types/struct_semid_ds.h b/sysdeps/unix/sysv/linux/x86/bits/types/struct_semid_ds.h
> index f7ec89d115..c3f2fde9fd 100644
> --- a/sysdeps/unix/sysv/linux/x86/bits/types/struct_semid_ds.h
> +++ b/sysdeps/unix/sysv/linux/x86/bits/types/struct_semid_ds.h
> @@ -25,9 +25,9 @@ struct semid_ds
>  {
>    struct ipc_perm sem_perm;   /* operation permission struct */
>    __time_t sem_otime;  /* last semop() time */
> -  __syscall_ulong_t __glibc_reserved1;
> +  __syscall_ulong_t __sem_otime_high;
>    __time_t sem_ctime;  /* last time changed by semctl() */
> -  __syscall_ulong_t __glibc_reserved2;
> +  __syscall_ulong_t __sem_ctime_high;
>    __syscall_ulong_t sem_nsems;    /* number of semaphores in set */
>    __syscall_ulong_t __glibc_reserved3;
>    __syscall_ulong_t __glibc_reserved4;
> --
> 2.25.1
>
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/7] sysvipc: Split out linux struct semid_ds

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
On Tue, Jun 30, 2020 at 12:24 PM Adhemerval Zanella via Libc-alpha
<[hidden email]> wrote:
>
> This will allow us to have architectures specify their own version.
>
> Not semantic changes expected.  Checked with a build against the
> all affected ABIs.

I have the exact same patch in my tree, looks good.

Reviewed-by: Alistair Francis <[hidden email]>

Alistair

> ---
>  sysdeps/unix/sysv/linux/Makefile              |  1 +
>  sysdeps/unix/sysv/linux/bits/msq.h            | 39 +++-----------
>  .../sysv/linux/bits/types/struct_msqid_ds.h   | 51 +++++++++++++++++++
>  3 files changed, 58 insertions(+), 33 deletions(-)
>  create mode 100644 sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
>
> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index e02065dc8d..70e2d9e044 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -92,6 +92,7 @@ sysdep_headers += sys/mount.h sys/acct.h \
>                   bits/termios-c_lflag.h bits/termios-tcflow.h \
>                   bits/termios-misc.h \
>                   bits/types/struct_semid_ds.h \
> +                 bits/types/struct_msqid_ds.h \
>                   bits/ipc-perm.h
>
>  tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
> diff --git a/sysdeps/unix/sysv/linux/bits/msq.h b/sysdeps/unix/sysv/linux/bits/msq.h
> index cc4ebae0f0..6ce6408ebc 100644
> --- a/sysdeps/unix/sysv/linux/bits/msq.h
> +++ b/sysdeps/unix/sysv/linux/bits/msq.h
> @@ -20,7 +20,12 @@
>  #endif
>
>  #include <bits/types.h>
> -#include <bits/msq-pad.h>
> +
> +/* Types used in the MSQID_DS structure definition.  */
> +typedef __syscall_ulong_t msgqnum_t;
> +typedef __syscall_ulong_t msglen_t;
> +
> +#include <bits/types/struct_msqid_ds.h>
>
>  /* Define options for message queue functions.  */
>  #define MSG_NOERROR    010000  /* no error if message is too big */
> @@ -29,38 +34,6 @@
>  # define MSG_COPY      040000  /* copy (not remove) all queue messages */
>  #endif
>
> -/* Types used in the structure definition.  */
> -typedef __syscall_ulong_t msgqnum_t;
> -typedef __syscall_ulong_t msglen_t;
> -
> -#if __MSQ_PAD_BEFORE_TIME
> -# define __MSQ_PAD_TIME(NAME, RES)                             \
> -  unsigned long int __glibc_reserved ## RES; __time_t NAME
> -#elif __MSQ_PAD_AFTER_TIME
> -# define __MSQ_PAD_TIME(NAME, RES)                             \
> -  __time_t NAME; unsigned long int __glibc_reserved ## RES
> -#else
> -# define __MSQ_PAD_TIME(NAME, RES)             \
> -  __time_t NAME
> -#endif
> -
> -/* Structure of record for one message inside the kernel.
> -   The type `struct msg' is opaque.  */
> -struct msqid_ds
> -{
> -  struct ipc_perm msg_perm;    /* structure describing operation permission */
> -  __MSQ_PAD_TIME (msg_stime, 1);       /* time of last msgsnd command */
> -  __MSQ_PAD_TIME (msg_rtime, 2);       /* time of last msgrcv command */
> -  __MSQ_PAD_TIME (msg_ctime, 3);       /* time of last change */
> -  __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */
> -  msgqnum_t msg_qnum;          /* number of messages currently on queue */
> -  msglen_t msg_qbytes;         /* max number of bytes allowed on queue */
> -  __pid_t msg_lspid;           /* pid of last msgsnd() */
> -  __pid_t msg_lrpid;           /* pid of last msgrcv() */
> -  __syscall_ulong_t __glibc_reserved4;
> -  __syscall_ulong_t __glibc_reserved5;
> -};
> -
>  #ifdef __USE_MISC
>
>  # define msg_cbytes    __msg_cbytes
> diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
> new file mode 100644
> index 0000000000..bfc56f6ac1
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
> @@ -0,0 +1,51 @@
> +/* Generic implementation of the SysV message struct msqid_ds.
> +   Copyright (C) 2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _SYS_MSG_H
> +# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
> +#endif
> +
> +#include <bits/msq-pad.h>
> +
> +#if __MSQ_PAD_BEFORE_TIME
> +# define __MSQ_PAD_TIME(NAME, RES)                             \
> +  unsigned long int __glibc_reserved ## RES; __time_t NAME
> +#elif __MSQ_PAD_AFTER_TIME
> +# define __MSQ_PAD_TIME(NAME, RES)                             \
> +  __time_t NAME; unsigned long int __glibc_reserved ## RES
> +#else
> +# define __MSQ_PAD_TIME(NAME, RES)             \
> +  __time_t NAME
> +#endif
> +
> +/* Structure of record for one message inside the kernel.
> +   The type `struct msg' is opaque.  */
> +struct msqid_ds
> +{
> +  struct ipc_perm msg_perm;    /* structure describing operation permission */
> +  __MSQ_PAD_TIME (msg_stime, 1);       /* time of last msgsnd command */
> +  __MSQ_PAD_TIME (msg_rtime, 2);       /* time of last msgrcv command */
> +  __MSQ_PAD_TIME (msg_ctime, 3);       /* time of last change */
> +  __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */
> +  msgqnum_t msg_qnum;          /* number of messages currently on queue */
> +  msglen_t msg_qbytes;         /* max number of bytes allowed on queue */
> +  __pid_t msg_lspid;           /* pid of last msgsnd() */
> +  __pid_t msg_lrpid;           /* pid of last msgrcv() */
> +  __syscall_ulong_t __glibc_reserved4;
> +  __syscall_ulong_t __glibc_reserved5;
> +};
> --
> 2.25.1
>
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 3/7] sysvipc: Remove the linux msq-pad.h file

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
On Tue, Jun 30, 2020 at 12:25 PM Adhemerval Zanella via Libc-alpha
<[hidden email]> wrote:

>
> Each architecture overrides the struct msqid_ds which its required
> kernel ABI one.
>
> Checked on x86_64-linux-gnu and some bases sysvipc tests on hppa,
> mips, mipsle, mips64, mips64le, sparc64, sparcv9, powerpc64le,
> powerpc64, and powerpc.
> ---
>  sysdeps/unix/sysv/linux/Makefile              |  2 +-
>  sysdeps/unix/sysv/linux/bits/msq-pad.h        | 31 ----------
>  .../sysv/linux/bits/types/struct_msqid_ds.h   | 28 ++++------
>  sysdeps/unix/sysv/linux/hppa/bits/msq-pad.h   | 26 ---------
>  .../linux/hppa/bits/types/struct_msqid_ds.h   | 47 ++++++++++++++++
>  sysdeps/unix/sysv/linux/mips/bits/msq-pad.h   | 31 ----------
>  .../linux/mips/bits/types/struct_msqid_ds.h   | 56 +++++++++++++++++++
>  .../unix/sysv/linux/powerpc/bits/msq-pad.h    | 26 ---------
>  .../powerpc/bits/types/struct_msqid_ds.h      | 47 ++++++++++++++++
>  sysdeps/unix/sysv/linux/sparc/bits/msq-pad.h  | 26 ---------
>  .../linux/sparc/bits/types/struct_msqid_ds.h  | 47 ++++++++++++++++
>  11 files changed, 210 insertions(+), 157 deletions(-)
>  delete mode 100644 sysdeps/unix/sysv/linux/bits/msq-pad.h
>  delete mode 100644 sysdeps/unix/sysv/linux/hppa/bits/msq-pad.h
>  create mode 100644 sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
>  delete mode 100644 sysdeps/unix/sysv/linux/mips/bits/msq-pad.h
>  create mode 100644 sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
>  delete mode 100644 sysdeps/unix/sysv/linux/powerpc/bits/msq-pad.h
>  create mode 100644 sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
>  delete mode 100644 sysdeps/unix/sysv/linux/sparc/bits/msq-pad.h
>  create mode 100644 sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h
>
> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index 70e2d9e044..505087e617 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -85,7 +85,7 @@ sysdep_headers += sys/mount.h sys/acct.h \
>                   bits/siginfo-arch.h bits/siginfo-consts-arch.h \
>                   bits/procfs.h bits/procfs-id.h bits/procfs-extra.h \
>                   bits/procfs-prregset.h bits/mman-map-flags-generic.h \
> -                 bits/msq-pad.h bits/shmlba.h bits/shm-pad.h \
> +                 bits/shmlba.h bits/shm-pad.h \
>                   bits/termios-struct.h bits/termios-c_cc.h \
>                   bits/termios-c_iflag.h bits/termios-c_oflag.h \
>                   bits/termios-baud.h bits/termios-c_cflag.h \
> diff --git a/sysdeps/unix/sysv/linux/bits/msq-pad.h b/sysdeps/unix/sysv/linux/bits/msq-pad.h
> deleted file mode 100644
> index e4ffd39f27..0000000000
> --- a/sysdeps/unix/sysv/linux/bits/msq-pad.h
> +++ /dev/null
> @@ -1,31 +0,0 @@
> -/* Define where padding goes in struct msqid_ds.  Generic version.
> -   Copyright (C) 2018-2020 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
> -   <https://www.gnu.org/licenses/>.  */
> -
> -#ifndef _SYS_MSG_H
> -# error "Never use <bits/msq-pad.h> directly; include <sys/msg.h> instead."
> -#endif
> -
> -#include <bits/timesize.h>
> -
> -/* On most architectures, padding goes after time fields for 32-bit
> -   systems and is omitted for 64-bit systems.  Some architectures pad
> -   before time fields instead, or omit padding despite being
> -   32-bit.  */
> -
> -#define __MSQ_PAD_AFTER_TIME (__TIMESIZE == 32)
> -#define __MSQ_PAD_BEFORE_TIME 0
> diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
> index bfc56f6ac1..32173a7b60 100644
> --- a/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
> +++ b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
> @@ -20,27 +20,23 @@
>  # error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
>  #endif
>
> -#include <bits/msq-pad.h>
> -
> -#if __MSQ_PAD_BEFORE_TIME
> -# define __MSQ_PAD_TIME(NAME, RES)                             \
> -  unsigned long int __glibc_reserved ## RES; __time_t NAME
> -#elif __MSQ_PAD_AFTER_TIME
> -# define __MSQ_PAD_TIME(NAME, RES)                             \
> -  __time_t NAME; unsigned long int __glibc_reserved ## RES
> -#else
> -# define __MSQ_PAD_TIME(NAME, RES)             \
> -  __time_t NAME
> -#endif
> -
>  /* Structure of record for one message inside the kernel.
>     The type `struct msg' is opaque.  */
>  struct msqid_ds
>  {
>    struct ipc_perm msg_perm;    /* structure describing operation permission */
> -  __MSQ_PAD_TIME (msg_stime, 1);       /* time of last msgsnd command */
> -  __MSQ_PAD_TIME (msg_rtime, 2);       /* time of last msgrcv command */
> -  __MSQ_PAD_TIME (msg_ctime, 3);       /* time of last change */
> +#if __TIMESIZE == 32
> +  __time_t msg_stime;          /* time of last msgsnd command */
> +  unsigned long int __glibc_reserved1;
> +  __time_t msg_rtime;          /* time of last msgsnd command */
> +  unsigned long int __glibc_reserved2;
> +  __time_t msg_ctime;          /* time of last change */
> +  unsigned long int __glibc_reserved3;
> +#else
> +  __time_t msg_stime;          /* time of last msgsnd command */
> +  __time_t msg_rtime;          /* time of last msgsnd command */
> +  __time_t msg_ctime;          /* time of last change */
> +#endif
>    __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */
>    msgqnum_t msg_qnum;          /* number of messages currently on queue */
>    msglen_t msg_qbytes;         /* max number of bytes allowed on queue */
> diff --git a/sysdeps/unix/sysv/linux/hppa/bits/msq-pad.h b/sysdeps/unix/sysv/linux/hppa/bits/msq-pad.h
> deleted file mode 100644
> index 6986585ae7..0000000000
> --- a/sysdeps/unix/sysv/linux/hppa/bits/msq-pad.h
> +++ /dev/null
> @@ -1,26 +0,0 @@
> -/* Define where padding goes in struct msqid_ds.  HPPA version.
> -   Copyright (C) 2018-2020 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
> -   <https://www.gnu.org/licenses/>.  */
> -
> -#ifndef _SYS_MSG_H
> -# error "Never use <bits/msq-pad.h> directly; include <sys/msg.h> instead."
> -#endif
> -
> -#include <bits/timesize.h>
> -
> -#define __MSQ_PAD_AFTER_TIME 0
> -#define __MSQ_PAD_BEFORE_TIME (__TIMESIZE == 32)
> diff --git a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
> new file mode 100644
> index 0000000000..3cf70e36c4
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
> @@ -0,0 +1,47 @@
> +/* Linux/HPPA implementation of the SysV message struct msqid_ds.
> +   Copyright (C) 2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _SYS_MSG_H
> +# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
> +#endif
> +
> +/* Structure of record for one message inside the kernel.
> +   The type `struct msg' is opaque.  */
> +struct msqid_ds
> +{
> +  struct ipc_perm msg_perm;    /* structure describing operation permission */
> +#if __TIMESIZE == 32
> +  unsigned long int __glibc_reserved1;
> +  __time_t msg_stime;          /* time of last msgsnd command */
> +  unsigned long int __glibc_reserved2;
> +  __time_t msg_rtime;          /* time of last msgsnd command */
> +  unsigned long int __glibc_reserved3;
> +  __time_t msg_ctime;          /* time of last change */
> +#else
> +  __time_t msg_stime;          /* time of last msgsnd command */
> +  __time_t msg_rtime;          /* time of last msgsnd command */
> +  __time_t msg_ctime;          /* time of last change */
> +#endif
> +  __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */
> +  msgqnum_t msg_qnum;          /* number of messages currently on queue */
> +  msglen_t msg_qbytes;         /* max number of bytes allowed on queue */
> +  __pid_t msg_lspid;           /* pid of last msgsnd() */
> +  __pid_t msg_lrpid;           /* pid of last msgrcv() */
> +  __syscall_ulong_t __glibc_reserved4;
> +  __syscall_ulong_t __glibc_reserved5;
> +};

Looks good.

> diff --git a/sysdeps/unix/sysv/linux/mips/bits/msq-pad.h b/sysdeps/unix/sysv/linux/mips/bits/msq-pad.h
> deleted file mode 100644
> index 8e28c5abe1..0000000000
> --- a/sysdeps/unix/sysv/linux/mips/bits/msq-pad.h
> +++ /dev/null
> @@ -1,31 +0,0 @@
> -/* Define where padding goes in struct msqid_ds.  MIPS version.
> -   Copyright (C) 2018-2020 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
> -   <https://www.gnu.org/licenses/>.  */
> -
> -#ifndef _SYS_MSG_H
> -# error "Never use <bits/msq-pad.h> directly; include <sys/msg.h> instead."
> -#endif
> -
> -#include <bits/timesize.h>
> -
> -#ifdef __MIPSEL__
> -# define __MSQ_PAD_AFTER_TIME (__TIMESIZE == 32)
> -# define __MSQ_PAD_BEFORE_TIME 0
> -#else
> -# define __MSQ_PAD_AFTER_TIME 0
> -# define __MSQ_PAD_BEFORE_TIME (__TIMESIZE == 32)
> -#endif
> diff --git a/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
> new file mode 100644
> index 0000000000..85fdeef274
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
> @@ -0,0 +1,56 @@
> +/* Linux/PowerPC implementation of the SysV message struct msqid_ds.

This should be MIPS, not PowerPC.

> +   Copyright (C) 2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _SYS_MSG_H
> +# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
> +#endif
> +
> +/* Structure of record for one message inside the kernel.
> +   The type `struct msg' is opaque.  */
> +struct msqid_ds
> +{
> +  struct ipc_perm msg_perm;    /* structure describing operation permission */
> +#if __TIMESIZE == 32
> +# ifdef __MIPSEL__
> +  __time_t msg_stime;          /* time of last msgsnd command */
> +  unsigned long int __glibc_reserved1;
> +  __time_t msg_rtime;          /* time of last msgsnd command */
> +  unsigned long int __glibc_reserved2;
> +  __time_t msg_ctime;          /* time of last change */
> +  unsigned long int __glibc_reserved3;
> +# else
> +  unsigned long int __glibc_reserved1;
> +  __time_t msg_stime;          /* time of last msgsnd command */
> +  unsigned long int __glibc_reserved2;
> +  __time_t msg_rtime;          /* time of last msgsnd command */
> +  unsigned long int __glibc_reserved3;
> +  __time_t msg_ctime;          /* time of last change */
> +# endif
> +#else
> +  __time_t msg_stime;          /* time of last msgsnd command */
> +  __time_t msg_rtime;          /* time of last msgsnd command */
> +  __time_t msg_ctime;          /* time of last change */
> +#endif
> +  __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */
> +  msgqnum_t msg_qnum;          /* number of messages currently on queue */
> +  msglen_t msg_qbytes;         /* max number of bytes allowed on queue */
> +  __pid_t msg_lspid;           /* pid of last msgsnd() */
> +  __pid_t msg_lrpid;           /* pid of last msgrcv() */
> +  __syscall_ulong_t __glibc_reserved4;
> +  __syscall_ulong_t __glibc_reserved5;
> +};

Implementation looks good.

> diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/msq-pad.h b/sysdeps/unix/sysv/linux/powerpc/bits/msq-pad.h
> deleted file mode 100644
> index e2b9310800..0000000000
> --- a/sysdeps/unix/sysv/linux/powerpc/bits/msq-pad.h
> +++ /dev/null
> @@ -1,26 +0,0 @@
> -/* Define where padding goes in struct msqid_ds.  PowerPC version.
> -   Copyright (C) 2018-2020 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
> -   <https://www.gnu.org/licenses/>.  */
> -
> -#ifndef _SYS_MSG_H
> -# error "Never use <bits/msq-pad.h> directly; include <sys/msg.h> instead."
> -#endif
> -
> -#include <bits/timesize.h>
> -
> -#define __MSQ_PAD_AFTER_TIME 0
> -#define __MSQ_PAD_BEFORE_TIME (__TIMESIZE == 32)
> diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
> new file mode 100644
> index 0000000000..4ae2fbcbdc
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
> @@ -0,0 +1,47 @@
> +/* Linux/PowerPC implementation of the SysV message struct msqid_ds.
> +   Copyright (C) 2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _SYS_MSG_H
> +# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
> +#endif
> +
> +/* Structure of record for one message inside the kernel.
> +   The type `struct msg' is opaque.  */
> +struct msqid_ds
> +{
> +  struct ipc_perm msg_perm;    /* structure describing operation permission */
> +#if __TIMESIZE == 32
> +  unsigned long int __glibc_reserved1;
> +  __time_t msg_stime;          /* time of last msgsnd command */
> +  unsigned long int __glibc_reserved2;
> +  __time_t msg_rtime;          /* time of last msgsnd command */
> +  unsigned long int __glibc_reserved3;
> +  __time_t msg_ctime;          /* time of last change */
> +#else
> +  __time_t msg_stime;          /* time of last msgsnd command */
> +  __time_t msg_rtime;          /* time of last msgsnd command */
> +  __time_t msg_ctime;          /* time of last change */
> +#endif
> +  __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */
> +  msgqnum_t msg_qnum;          /* number of messages currently on queue */
> +  msglen_t msg_qbytes;         /* max number of bytes allowed on queue */
> +  __pid_t msg_lspid;           /* pid of last msgsnd() */
> +  __pid_t msg_lrpid;           /* pid of last msgrcv() */
> +  __syscall_ulong_t __glibc_reserved4;
> +  __syscall_ulong_t __glibc_reserved5;
> +};

Looks good.

> diff --git a/sysdeps/unix/sysv/linux/sparc/bits/msq-pad.h b/sysdeps/unix/sysv/linux/sparc/bits/msq-pad.h
> deleted file mode 100644
> index 99fdf8c8f0..0000000000
> --- a/sysdeps/unix/sysv/linux/sparc/bits/msq-pad.h
> +++ /dev/null
> @@ -1,26 +0,0 @@
> -/* Define where padding goes in struct msqid_ds.  SPARC version.
> -   Copyright (C) 2018-2020 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
> -   <https://www.gnu.org/licenses/>.  */
> -
> -#ifndef _SYS_MSG_H
> -# error "Never use <bits/msq-pad.h> directly; include <sys/msg.h> instead."
> -#endif
> -
> -#include <bits/timesize.h>
> -
> -#define __MSQ_PAD_AFTER_TIME 0
> -#define __MSQ_PAD_BEFORE_TIME (__TIMESIZE == 32)
> diff --git a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h
> new file mode 100644
> index 0000000000..71980839c7
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h
> @@ -0,0 +1,47 @@
> +/* Linux/SPARC implementation of the SysV message struct msqid_ds.
> +   Copyright (C) 2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _SYS_MSG_H
> +# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
> +#endif
> +
> +/* Structure of record for one message inside the kernel.
> +   The type `struct msg' is opaque.  */
> +struct msqid_ds
> +{
> +  struct ipc_perm msg_perm;    /* structure describing operation permission */
> +#if __TIMESIZE == 32
> +  unsigned long int __glibc_reserved1;
> +  __time_t msg_stime;          /* time of last msgsnd command */
> +  unsigned long int __glibc_reserved2;
> +  __time_t msg_rtime;          /* time of last msgsnd command */
> +  unsigned long int __glibc_reserved3;
> +  __time_t msg_ctime;          /* time of last change */
> +#else
> +  __time_t msg_stime;          /* time of last msgsnd command */
> +  __time_t msg_rtime;          /* time of last msgsnd command */
> +  __time_t msg_ctime;          /* time of last change */
> +#endif
> +  __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */
> +  msgqnum_t msg_qnum;          /* number of messages currently on queue */
> +  msglen_t msg_qbytes;         /* max number of bytes allowed on queue */
> +  __pid_t msg_lspid;           /* pid of last msgsnd() */
> +  __pid_t msg_lrpid;           /* pid of last msgrcv() */
> +  __syscall_ulong_t __glibc_reserved4;
> +  __syscall_ulong_t __glibc_reserved5;
> +};

Looks good.

Alistair

> --
> 2.25.1
>
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 4/7] sysv: linux: Add 64-bit time_t variant for msgctl

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
On Tue, Jun 30, 2020 at 12:27 PM Adhemerval Zanella via Libc-alpha
<[hidden email]> wrote:

>
> To provide a y2038 safe interface a new symbol __msgctl64 is added
> and __msgctl is change to call it instead (it adds some extra buffer
> copy for the 32 bit time_t implementation).
>
> Two two new structures are added:
>
>   1. kernel_msqid64_ds: used internally only on 32-bit architectures
>      to issue the syscall.  A handful architectures (hppa, i386, mips,
>      powerpc32, and sparc32) requires specific implementation due its
>      specific kernel ABI.
>
>   2. msqid_ds64: this is only for __TIMESIZE != 64 to use along with
>      the 64-bit semctl.  It is different than the kernel one because
>      the exported 64-bit time_t might require different alignment
>      depending of the architecture ABI.
>
> So the resulting implementation does:
>
>   1. For 64-bit architectures it assumes msqid_ds already contains
>      64-bit time_t fields it will result in just the __msgctl symbol
>      using the __msgctl64 code.  The msgid_ds argument is passed as-is
>      to the syscall.
>
>   2. For 32-bit architectures with default 64-bit time_t (newer ABIs
>      such riscv32 or arc), it will also result in only one exported
>      symbol but with the required high/low time handling.
>
>   3. Finally for 32-bit architecture with both 32-bit and 64-bit time_t
>      support we follow the already set way to provide one symbol with
>      64-bit time_t support and implement the 32-bit time_t support on
>      basis of the 64-bit one.
>
>      The default 32-bit symbol will allocate and copy the msqid_ds
>      over multiple buffers, but this should be deprecated in favor
>      of the __msgctl64 anyway.
>
> Checked on i686-linux-gnu and x86_64-linux-gnu.  I also did some sniff
> tests on powerpc, powerpc64, mips, mips64, armhf, sparcv9, and
> sparc64.
> ---
>  include/sys/msg.h                             |  10 +
>  .../sysv/linux/bits/types/struct_msqid64_ds.h |  38 ++++
>  .../sysv/linux/bits/types/struct_msqid_ds.h   |   6 +-
>  .../linux/hppa/bits/types/struct_msqid_ds.h   |   6 +-
>  .../linux/hppa/struct_kernel_msqid64_ds.h     |  18 ++
>  .../linux/i386/struct_kernel_msqid64_ds.h     |  18 ++
>  .../linux/mips/bits/types/struct_msqid_ds.h   |  12 +-
>  .../linux/mips/struct_kernel_msqid64_ds.h     |  33 ++++
>  sysdeps/unix/sysv/linux/msgctl.c              | 179 ++++++++++++++----
>  .../powerpc/bits/types/struct_msqid_ds.h      |   6 +-
>  .../powerpc32/struct_kernel_msqid64_ds.h      |  18 ++
>  sysdeps/unix/sysv/linux/semctl.c              |  27 +--
>  .../linux/sparc/bits/types/struct_msqid_ds.h  |   6 +-
>  .../sparc/sparc32/struct_kernel_msqid64_ds.h  |  18 ++
>  .../sysv/linux/struct_kernel_msqid64_ds.h     |  19 ++
>  15 files changed, 350 insertions(+), 64 deletions(-)
>  create mode 100644 sysdeps/unix/sysv/linux/bits/types/struct_msqid64_ds.h
>  create mode 100644 sysdeps/unix/sysv/linux/hppa/struct_kernel_msqid64_ds.h
>  create mode 100644 sysdeps/unix/sysv/linux/i386/struct_kernel_msqid64_ds.h
>  create mode 100644 sysdeps/unix/sysv/linux/mips/struct_kernel_msqid64_ds.h
>  create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/struct_kernel_msqid64_ds.h
>  create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/struct_kernel_msqid64_ds.h
>  create mode 100644 sysdeps/unix/sysv/linux/struct_kernel_msqid64_ds.h
>
> diff --git a/include/sys/msg.h b/include/sys/msg.h
> index 43ec5b9472..522903f818 100644
> --- a/include/sys/msg.h
> +++ b/include/sys/msg.h
> @@ -6,6 +6,16 @@ extern ssize_t __libc_msgrcv (int msqid, void *msgp, size_t msgsz,
>                               long int msgtyp, int msgflg);
>  extern int __libc_msgsnd (int msqid, const void *msgp, size_t msgsz,
>                           int msgflg);
> +
> +# include <bits/types/struct_msqid64_ds.h>
> +
> +# if __TIMESIZE == 64
> +#  define __msgctl64 __msgctl
> +# else
> +extern int __msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf);
> +libc_hidden_proto (__msgctl64);
> +# endif
> +
>  #endif
>
>  #endif
> diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_msqid64_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_msqid64_ds.h
> new file mode 100644
> index 0000000000..3536c8ea62
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/bits/types/struct_msqid64_ds.h
> @@ -0,0 +1,38 @@
> +/* Generic implementation of the SysV message struct msqid64_ds.
> +   Copyright (C) 2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _SYS_MSG_H
> +# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
> +#endif
> +
> +#if __TIMESIZE == 64
> +# define __msqid64_ds msqid_ds
> +#else
> +struct __msqid64_ds
> +{
> +  struct ipc_perm msg_perm;    /* structure describing operation permission */
> +  __time64_t msg_stime;                /* time of last msgsnd command */
> +  __time64_t msg_rtime;                /* time of last msgsnd command */
> +  __time64_t msg_ctime;                /* time of last change */
> +  __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */
> +  msgqnum_t msg_qnum;          /* number of messages currently on queue */
> +  msglen_t msg_qbytes;         /* max number of bytes allowed on queue */
> +  __pid_t msg_lspid;           /* pid of last msgsnd() */
> +  __pid_t msg_lrpid;           /* pid of last msgrcv() */
> +};
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
> index 32173a7b60..43b38175ad 100644
> --- a/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
> +++ b/sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
> @@ -27,11 +27,11 @@ struct msqid_ds
>    struct ipc_perm msg_perm;    /* structure describing operation permission */
>  #if __TIMESIZE == 32
>    __time_t msg_stime;          /* time of last msgsnd command */
> -  unsigned long int __glibc_reserved1;
> +  unsigned long int __msg_stime_high;
>    __time_t msg_rtime;          /* time of last msgsnd command */
> -  unsigned long int __glibc_reserved2;
> +  unsigned long int __msg_rtime_high;
>    __time_t msg_ctime;          /* time of last change */
> -  unsigned long int __glibc_reserved3;
> +  unsigned long int __msg_ctime_high;
>  #else
>    __time_t msg_stime;          /* time of last msgsnd command */
>    __time_t msg_rtime;          /* time of last msgsnd command */
> diff --git a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
> index 3cf70e36c4..16eac46941 100644
> --- a/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
> +++ b/sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
> @@ -26,11 +26,11 @@ struct msqid_ds
>  {
>    struct ipc_perm msg_perm;    /* structure describing operation permission */
>  #if __TIMESIZE == 32
> -  unsigned long int __glibc_reserved1;
> +  unsigned long int __msg_stime_high;
>    __time_t msg_stime;          /* time of last msgsnd command */
> -  unsigned long int __glibc_reserved2;
> +  unsigned long int __msg_rtime_high;
>    __time_t msg_rtime;          /* time of last msgsnd command */
> -  unsigned long int __glibc_reserved3;
> +  unsigned long int __msg_ctime_high;
>    __time_t msg_ctime;          /* time of last change */
>  #else
>    __time_t msg_stime;          /* time of last msgsnd command */
> diff --git a/sysdeps/unix/sysv/linux/hppa/struct_kernel_msqid64_ds.h b/sysdeps/unix/sysv/linux/hppa/struct_kernel_msqid64_ds.h
> new file mode 100644
> index 0000000000..69a63ee27a
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/hppa/struct_kernel_msqid64_ds.h
> @@ -0,0 +1,18 @@
> +/* Analogous to kernel struct msqid64_ds used on msgctl.  */
> +struct kernel_msqid64_ds
> +{
> +  struct ipc_perm msg_perm;
> +  unsigned long msg_stime_high;
> +  unsigned long msg_stime;
> +  unsigned long msg_rtime_high;
> +  unsigned long msg_rtime;
> +  unsigned long msg_ctime_high;
> +  unsigned long msg_ctime;
> +  unsigned long msg_cbytes;
> +  unsigned long msg_qnum;
> +  unsigned long msg_qbytes;
> +  __pid_t msg_lspid;
> +  __pid_t msg_lrpid;
> +  unsigned long __unused1;
> +  unsigned long __unused2;
> +};
> diff --git a/sysdeps/unix/sysv/linux/i386/struct_kernel_msqid64_ds.h b/sysdeps/unix/sysv/linux/i386/struct_kernel_msqid64_ds.h
> new file mode 100644
> index 0000000000..65b940567b
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/i386/struct_kernel_msqid64_ds.h
> @@ -0,0 +1,18 @@
> +/* Analogous to kernel struct compat_msqid64_ds used on msgctl.  */
> +struct kernel_msqid64_ds
> +{
> +  struct ipc_perm msg_perm;
> +  unsigned long msg_stime;
> +  unsigned long msg_stime_high;
> +  unsigned long msg_rtime;
> +  unsigned long msg_rtime_high;
> +  unsigned long msg_ctime;
> +  unsigned long msg_ctime_high;
> +  unsigned long msg_cbytes;
> +  unsigned long msg_qnum;
> +  unsigned long msg_qbytes;
> +  __pid_t msg_lspid;
> +  __pid_t msg_lrpid;
> +  unsigned long __unused1;
> +  unsigned long __unused2;
> +};
> diff --git a/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
> index 85fdeef274..9ff010c763 100644
> --- a/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
> +++ b/sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
> @@ -28,17 +28,17 @@ struct msqid_ds
>  #if __TIMESIZE == 32
>  # ifdef __MIPSEL__
>    __time_t msg_stime;          /* time of last msgsnd command */
> -  unsigned long int __glibc_reserved1;
> +  unsigned long int __msg_stime_high;
>    __time_t msg_rtime;          /* time of last msgsnd command */
> -  unsigned long int __glibc_reserved2;
> +  unsigned long int __msg_rtime_high;
>    __time_t msg_ctime;          /* time of last change */
> -  unsigned long int __glibc_reserved3;
> +  unsigned long int __msg_ctime_high;
>  # else
> -  unsigned long int __glibc_reserved1;
> +  unsigned long int __msg_stime_high;
>    __time_t msg_stime;          /* time of last msgsnd command */
> -  unsigned long int __glibc_reserved2;
> +  unsigned long int __msg_rtime_high;
>    __time_t msg_rtime;          /* time of last msgsnd command */
> -  unsigned long int __glibc_reserved3;
> +  unsigned long int __msg_ctime_high;
>    __time_t msg_ctime;          /* time of last change */
>  # endif
>  #else
> diff --git a/sysdeps/unix/sysv/linux/mips/struct_kernel_msqid64_ds.h b/sysdeps/unix/sysv/linux/mips/struct_kernel_msqid64_ds.h
> new file mode 100644
> index 0000000000..9cfd5a0dfe
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/mips/struct_kernel_msqid64_ds.h
> @@ -0,0 +1,33 @@
> +/* Analogous to kernel struct msqid64_ds used on msgctl.  */
> +struct kernel_msqid64_ds
> +{
> +  struct ipc_perm msg_perm;
> +#if __TIMESIZE == 32
> +# ifdef __MIPSEL__
> +  unsigned long int msg_stime;
> +  unsigned long int msg_stime_high;
> +  unsigned long int msg_rtime;
> +  unsigned long int msg_rtime_high;
> +  unsigned long int msg_ctime;
> +  unsigned long int msg_ctime_high;
> +# else
> +  unsigned long int msg_stime_high;
> +  unsigned long int msg_stime;
> +  unsigned long int msg_rtime_high;
> +  unsigned long int msg_rtime;
> +  unsigned long int msg_ctime_high;
> +  unsigned long int msg_ctime;
> +# endif
> +#else
> +  unsigned long int msg_stime;
> +  unsigned long int msg_rtime;
> +  unsigned long int msg_ctime;
> +#endif
> +  unsigned long int msg_cbytes;
> +  unsigned long int msg_qnum;
> +  unsigned long int msg_qbytes;
> +  __pid_t msg_lspid;
> +  __pid_t msg_lrpid;
> +  unsigned long int __unused1;
> +  unsigned long int __unused2;
> +};
> diff --git a/sysdeps/unix/sysv/linux/msgctl.c b/sysdeps/unix/sysv/linux/msgctl.c
> index fd46aec1a0..a7f7651280 100644
> --- a/sysdeps/unix/sysv/linux/msgctl.c
> +++ b/sysdeps/unix/sysv/linux/msgctl.c
> @@ -23,16 +23,55 @@
>  #include <errno.h>
>  #include <linux/posix_types.h>  /* For __kernel_mode_t.  */
>
> -#ifndef DEFAULT_VERSION
> -# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T
> -#  define DEFAULT_VERSION GLIBC_2_2
> -# else
> -#  define DEFAULT_VERSION GLIBC_2_31
> -# endif
> +/* POSIX states ipc_perm mode should have type of mode_t.  */
> +_Static_assert (sizeof ((struct msqid_ds){0}.msg_perm.mode)
> +               == sizeof (mode_t),
> +               "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)");
> +
> +#if __IPC_TIME64 == 0
> +typedef struct msqid_ds msgctl_arg_t;
> +#else
> +# include <struct_kernel_msqid64_ds.h>
> +
> +static void
> +msqid64_to_kmsqid64 (const struct __msqid64_ds *msqid64,
> +                    struct kernel_msqid64_ds *kmsqid)
> +{
> +  kmsqid->msg_perm       = msqid64->msg_perm;
> +  kmsqid->msg_stime      = msqid64->msg_stime;
> +  kmsqid->msg_stime_high = msqid64->msg_stime >> 32;
> +  kmsqid->msg_rtime      = msqid64->msg_rtime;
> +  kmsqid->msg_rtime_high = msqid64->msg_rtime >> 32;
> +  kmsqid->msg_ctime      = msqid64->msg_ctime;
> +  kmsqid->msg_ctime_high = msqid64->msg_ctime >> 32;
> +  kmsqid->msg_qnum       = msqid64->msg_qnum;
> +  kmsqid->msg_qbytes     = msqid64->msg_qbytes;
> +  kmsqid->msg_lspid      = msqid64->msg_lspid;
> +  kmsqid->msg_lrpid      = msqid64->msg_lrpid;
> +}
> +
> +static void
> +kmsqid64_to_msqid64 (const struct kernel_msqid64_ds *kmsqid,
> +                    struct __msqid64_ds *msqid64)
> +{
> +  msqid64->msg_perm   = kmsqid->msg_perm;
> +  msqid64->msg_stime  = kmsqid->msg_stime
> +                       | ((__time64_t) kmsqid->msg_stime_high << 32);
> +  msqid64->msg_rtime  = kmsqid->msg_rtime
> +                       | ((__time64_t) kmsqid->msg_rtime_high << 32);
> +  msqid64->msg_ctime  = kmsqid->msg_ctime
> +                       | ((__time64_t) kmsqid->msg_ctime_high << 32);
> +  msqid64->msg_qnum   = kmsqid->msg_qnum;
> +  msqid64->msg_qbytes = kmsqid->msg_qbytes;
> +  msqid64->msg_lspid  = kmsqid->msg_lspid;
> +  msqid64->msg_lrpid  = kmsqid->msg_lrpid;
> +}
> +
> +typedef struct kernel_msqid64_ds msgctl_arg_t;
>  #endif
>
>  static int
> -msgctl_syscall (int msqid, int cmd, struct msqid_ds *buf)
> +msgctl_syscall (int msqid, int cmd, msgctl_arg_t *buf)
>  {
>  #ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
>    return INLINE_SYSCALL_CALL (msgctl, msqid, cmd | __IPC_64, buf);
> @@ -43,46 +82,118 @@ msgctl_syscall (int msqid, int cmd, struct msqid_ds *buf)
>  }
>
>  int
> -__new_msgctl (int msqid, int cmd, struct msqid_ds *buf)
> +__msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf)
>  {
> -  /* POSIX states ipc_perm mode should have type of mode_t.  */
> -  _Static_assert (sizeof ((struct msqid_ds){0}.msg_perm.mode)
> -                 == sizeof (mode_t),
> -                 "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)");
> -
> -#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
> -  struct msqid_ds tmpds;
> -  if (cmd == IPC_SET)
> +#if __IPC_TIME64
> +  struct kernel_msqid64_ds ksemid, *arg = NULL;
> +  if (buf != NULL)
>      {
> -      tmpds = *buf;
> -      tmpds.msg_perm.mode *= 0x10000U;
> -      buf = &tmpds;
> +      msqid64_to_kmsqid64 (buf, &ksemid);
> +      arg = &ksemid;
>      }
> +# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
> +  if (cmd == IPC_SET)
> +    arg->msg_perm.mode *= 0x10000U;
> +# endif
> +#else
> +  msgctl_arg_t *arg = buf;
>  #endif
>
> -  int ret = msgctl_syscall (msqid, cmd, buf);
> +  int ret = msgctl_syscall (msqid, cmd, arg);
> +  if (ret < 0)
> +    return ret;
>
> -  if (ret >= 0)
> +  switch (cmd)
>      {
> -      switch (cmd)
> -       {
> -       case IPC_STAT:
> -       case MSG_STAT:
> -       case MSG_STAT_ANY:
> +    case IPC_STAT:
> +    case MSG_STAT:
> +    case MSG_STAT_ANY:
>  #ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
> -         buf->msg_perm.mode >>= 16;
> +      arg->msg_perm.mode >>= 16;
>  #else
> -         /* Old Linux kernel versions might not clear the mode padding.  */
> -         if (sizeof ((struct msqid_ds){0}.msg_perm.mode)
> -             != sizeof (__kernel_mode_t))
> -           buf->msg_perm.mode &= 0xFFFF;
> +      /* Old Linux kernel versions might not clear the mode padding.  */
> +      if (sizeof ((struct msqid_ds){0}.msg_perm.mode)
> +          != sizeof (__kernel_mode_t))
> +       arg->msg_perm.mode &= 0xFFFF;
> +#endif
> +
> +#if __IPC_TIME64
> +      kmsqid64_to_msqid64 (arg, buf);
>  #endif
> -       }
>      }
>
>    return ret;
>  }
> -versioned_symbol (libc, __new_msgctl, msgctl, DEFAULT_VERSION);
> +#if __TIMESIZE != 64
> +libc_hidden_def (__msgctl64)
> +
> +static void
> +msqid_to_msqid64 (struct __msqid64_ds *mq64, const struct msqid_ds *mq)
> +{
> +  mq64->msg_perm   = mq->msg_perm;
> +  mq64->msg_stime  = mq->msg_stime
> +                    | ((__time64_t) mq->__msg_stime_high << 32);
> +  mq64->msg_rtime  = mq->msg_rtime
> +                    | ((__time64_t) mq->__msg_rtime_high << 32);
> +  mq64->msg_ctime  = mq->msg_ctime
> +                    | ((__time64_t) mq->__msg_ctime_high << 32);
> +  mq64->msg_qnum   = mq->msg_qnum;
> +  mq64->msg_qbytes = mq->msg_qbytes;
> +  mq64->msg_lspid  = mq->msg_lspid;
> +  mq64->msg_lrpid  = mq->msg_lrpid;
> +}
> +
> +static void
> +msqid64_to_msqid (struct msqid_ds *mq, const struct __msqid64_ds *mq64)
> +{
> +  mq->msg_perm         = mq64->msg_perm;
> +  mq->msg_stime        = mq64->msg_stime;
> +  mq->__msg_stime_high = 0;
> +  mq->msg_rtime        = mq64->msg_rtime;
> +  mq->__msg_rtime_high = 0;
> +  mq->msg_ctime        = mq64->msg_ctime;
> +  mq->__msg_ctime_high = 0;
> +  mq->msg_qnum         = mq64->msg_qnum;
> +  mq->msg_qbytes       = mq64->msg_qbytes;
> +  mq->msg_lspid        = mq64->msg_lspid;
> +  mq->msg_lrpid        = mq64->msg_lrpid;
> +}
> +
> +int
> +__msgctl (int msqid, int cmd, struct msqid_ds *buf)
> +{
> +  struct __msqid64_ds msqid64, *buf64 = NULL;
> +  if (buf != NULL)
> +    {
> +      msqid_to_msqid64 (&msqid64, buf);
> +      buf64 = &msqid64;
> +    }
> +
> +  int ret = __msgctl64 (msqid, cmd, buf64);
> +  if (ret < 0)
> +    return ret;
> +
> +  switch (cmd)
> +    {
> +    case IPC_STAT:
> +    case MSG_STAT:
> +    case MSG_STAT_ANY:
> +      if (buf64 != NULL)
> +        msqid64_to_msqid (buf, buf64);
> +    }
> +
> +  return ret;
> +}
> +#endif
> +
> +#ifndef DEFAULT_VERSION
> +# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T
> +#  define DEFAULT_VERSION GLIBC_2_2
> +# else
> +#  define DEFAULT_VERSION GLIBC_2_31
> +# endif
> +#endif
> +versioned_symbol (libc, __msgctl, msgctl, DEFAULT_VERSION);
>
>  #if defined __ASSUME_SYSVIPC_BROKEN_MODE_T \
>      && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_31)
> @@ -90,7 +201,7 @@ int
>  attribute_compat_text_section
>  __msgctl_mode16 (int msqid, int cmd, struct msqid_ds *buf)
>  {
> -  return msgctl_syscall (msqid, cmd, buf);
> +  return msgctl_syscall (msqid, cmd, (msgctl_arg_t *) buf);
>  }
>  compat_symbol (libc, __msgctl_mode16, msgctl, GLIBC_2_2);
>  #endif

Shouldn't everything below here be in a separate patch?

Alistair

> diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
> index 4ae2fbcbdc..35cc51f733 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
> +++ b/sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
> @@ -26,11 +26,11 @@ struct msqid_ds
>  {
>    struct ipc_perm msg_perm;    /* structure describing operation permission */
>  #if __TIMESIZE == 32
> -  unsigned long int __glibc_reserved1;
> +  unsigned long int __msg_stime_high;
>    __time_t msg_stime;          /* time of last msgsnd command */
> -  unsigned long int __glibc_reserved2;
> +  unsigned long int __msg_rtime_high;
>    __time_t msg_rtime;          /* time of last msgsnd command */
> -  unsigned long int __glibc_reserved3;
> +  unsigned long int __msg_ctime_high;
>    __time_t msg_ctime;          /* time of last change */
>  #else
>    __time_t msg_stime;          /* time of last msgsnd command */
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/struct_kernel_msqid64_ds.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/struct_kernel_msqid64_ds.h
> new file mode 100644
> index 0000000000..69a63ee27a
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/struct_kernel_msqid64_ds.h
> @@ -0,0 +1,18 @@
> +/* Analogous to kernel struct msqid64_ds used on msgctl.  */
> +struct kernel_msqid64_ds
> +{
> +  struct ipc_perm msg_perm;
> +  unsigned long msg_stime_high;
> +  unsigned long msg_stime;
> +  unsigned long msg_rtime_high;
> +  unsigned long msg_rtime;
> +  unsigned long msg_ctime_high;
> +  unsigned long msg_ctime;
> +  unsigned long msg_cbytes;
> +  unsigned long msg_qnum;
> +  unsigned long msg_qbytes;
> +  __pid_t msg_lspid;
> +  __pid_t msg_lrpid;
> +  unsigned long __unused1;
> +  unsigned long __unused2;
> +};
> diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c
> index 3a06270242..7467d2566e 100644
> --- a/sysdeps/unix/sysv/linux/semctl.c
> +++ b/sysdeps/unix/sysv/linux/semctl.c
> @@ -196,19 +196,11 @@ libc_hidden_def (__semctl64)
>
>  /* The 64-bit time_t semid_ds version might have a different layout and
>     internal field alignment.  */
> -static void
> -semid64_ds_to_semid_ds (struct semid_ds *ds, const struct __semid64_ds *ds64)
> -{
> -  ds->sem_perm = ds64->sem_perm;
> -  ds->sem_otime = ds64->sem_otime;
> -  ds->sem_ctime = ds64->sem_ctime;
> -  ds->sem_nsems = ds64->sem_nsems;
> -}
>
>  static void
> -semid_ds_to_semid64_ds (struct __semid64_ds *ds64, const struct semid_ds *ds)
> +semid_to_semid64 (struct __semid64_ds *ds64, const struct semid_ds *ds)
>  {
> -  ds64->sem_perm = ds->sem_perm;
> +  ds64->sem_perm  = ds->sem_perm;
>    ds64->sem_otime = ds->sem_otime
>                     | ((__time64_t) ds->__sem_otime_high << 32);
>    ds64->sem_ctime = ds->sem_ctime
> @@ -216,6 +208,17 @@ semid_ds_to_semid64_ds (struct __semid64_ds *ds64, const struct semid_ds *ds)
>    ds64->sem_nsems = ds->sem_nsems;
>  }
>
> +static void
> +semid64_to_semid (struct semid_ds *ds, const struct __semid64_ds *ds64)
> +{
> +  ds->sem_perm         = ds64->sem_perm;
> +  ds->sem_otime        = ds64->sem_otime;
> +  ds->__sem_otime_high = 0;
> +  ds->sem_ctime        = ds64->sem_ctime;
> +  ds->__sem_ctime_high = 0;
> +  ds->sem_nsems        = ds64->sem_nsems;
> +}
> +
>  static union semun64
>  semun_to_semun64 (int cmd, union semun semun, struct __semid64_ds *semid64)
>  {
> @@ -232,7 +235,7 @@ semun_to_semun64 (int cmd, union semun semun, struct __semid64_ds *semid64)
>      case IPC_STAT:
>      case IPC_SET:
>        r.buf = semid64;
> -      semid_ds_to_semid64_ds (r.buf, semun.buf);
> +      semid_to_semid64 (r.buf, semun.buf);
>  # ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
>        if (cmd == IPC_SET)
>         r.buf->sem_perm.mode *= 0x10000U;
> @@ -282,7 +285,7 @@ __semctl (int semid, int semnum, int cmd, ...)
>      case IPC_STAT:
>      case SEM_STAT:
>      case SEM_STAT_ANY:
> -      semid64_ds_to_semid_ds (arg.buf, arg64.buf);
> +      semid64_to_semid (arg.buf, arg64.buf);
>      }
>
>    return ret;
> diff --git a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h
> index 71980839c7..502c23d91e 100644
> --- a/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h
> +++ b/sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h
> @@ -26,11 +26,11 @@ struct msqid_ds
>  {
>    struct ipc_perm msg_perm;    /* structure describing operation permission */
>  #if __TIMESIZE == 32
> -  unsigned long int __glibc_reserved1;
> +  unsigned long int __msg_stime_high;
>    __time_t msg_stime;          /* time of last msgsnd command */
> -  unsigned long int __glibc_reserved2;
> +  unsigned long int __msg_rtime_high;
>    __time_t msg_rtime;          /* time of last msgsnd command */
> -  unsigned long int __glibc_reserved3;
> +  unsigned long int __msg_ctime_high;
>    __time_t msg_ctime;          /* time of last change */
>  #else
>    __time_t msg_stime;          /* time of last msgsnd command */
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/struct_kernel_msqid64_ds.h b/sysdeps/unix/sysv/linux/sparc/sparc32/struct_kernel_msqid64_ds.h
> new file mode 100644
> index 0000000000..69a63ee27a
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/struct_kernel_msqid64_ds.h
> @@ -0,0 +1,18 @@
> +/* Analogous to kernel struct msqid64_ds used on msgctl.  */
> +struct kernel_msqid64_ds
> +{
> +  struct ipc_perm msg_perm;
> +  unsigned long msg_stime_high;
> +  unsigned long msg_stime;
> +  unsigned long msg_rtime_high;
> +  unsigned long msg_rtime;
> +  unsigned long msg_ctime_high;
> +  unsigned long msg_ctime;
> +  unsigned long msg_cbytes;
> +  unsigned long msg_qnum;
> +  unsigned long msg_qbytes;
> +  __pid_t msg_lspid;
> +  __pid_t msg_lrpid;
> +  unsigned long __unused1;
> +  unsigned long __unused2;
> +};
> diff --git a/sysdeps/unix/sysv/linux/struct_kernel_msqid64_ds.h b/sysdeps/unix/sysv/linux/struct_kernel_msqid64_ds.h
> new file mode 100644
> index 0000000000..a676e34a5a
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/struct_kernel_msqid64_ds.h
> @@ -0,0 +1,19 @@
> +/* Analogous to kernel struct msqid64_ds used on msgctl.  It is only used
> +   for 32-bit architectures on 64-bit time_t msgctl64 implementation.  */
> +struct kernel_msqid64_ds
> +{
> +  struct ipc_perm msg_perm;
> +  unsigned long int msg_stime;
> +  unsigned long int msg_stime_high;
> +  unsigned long int msg_rtime;
> +  unsigned long int msg_rtime_high;
> +  unsigned long int msg_ctime;
> +  unsigned long int msg_ctime_high;
> +  unsigned long int msg_cbytes;
> +  unsigned long int msg_qnum;
> +  unsigned long int  msg_qbytes;
> +  __pid_t msg_lspid;
> +  __pid_t msg_lrpid;
> +  unsigned long int __unused4;
> +  unsigned long int __unused5;
> +};
> --
> 2.25.1
>
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 5/7] sysvipc: Split out linux struct shmid_ds

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
On Tue, Jun 30, 2020 at 12:27 PM Adhemerval Zanella via Libc-alpha
<[hidden email]> wrote:
>
> This will allow us to have architectures specify their own version.
>
> Not semantic changes expected.  Checked with a build against the
> all affected ABIs.

Reviewed-by: Alistair Francis <[hidden email]>

Alistair

> ---
>  sysdeps/unix/sysv/linux/Makefile              |  1 +
>  sysdeps/unix/sysv/linux/bits/shm.h            | 34 +----------
>  .../sysv/linux/bits/types/struct_shmid_ds.h   | 57 +++++++++++++++++++
>  3 files changed, 59 insertions(+), 33 deletions(-)
>  create mode 100644 sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h
>
> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index 505087e617..bdd187af73 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -93,6 +93,7 @@ sysdep_headers += sys/mount.h sys/acct.h \
>                   bits/termios-misc.h \
>                   bits/types/struct_semid_ds.h \
>                   bits/types/struct_msqid_ds.h \
> +                 bits/types/struct_shmid_ds.h \
>                   bits/ipc-perm.h
>
>  tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
> diff --git a/sysdeps/unix/sysv/linux/bits/shm.h b/sysdeps/unix/sysv/linux/bits/shm.h
> index 113c05ee89..9ef6aeaf92 100644
> --- a/sysdeps/unix/sysv/linux/bits/shm.h
> +++ b/sysdeps/unix/sysv/linux/bits/shm.h
> @@ -43,39 +43,7 @@ __BEGIN_DECLS
>  /* Type to count number of attaches.  */
>  typedef __syscall_ulong_t shmatt_t;
>
> -#if __SHM_PAD_BEFORE_TIME
> -# define __SHM_PAD_TIME(NAME, RES)                             \
> -  unsigned long int __glibc_reserved ## RES; __time_t NAME
> -#elif __SHM_PAD_AFTER_TIME
> -# define __SHM_PAD_TIME(NAME, RES)                             \
> -  __time_t NAME; unsigned long int __glibc_reserved ## RES
> -#else
> -# define __SHM_PAD_TIME(NAME, RES)             \
> -  __time_t NAME
> -#endif
> -
> -/* Data structure describing a shared memory segment.  */
> -struct shmid_ds
> -  {
> -    struct ipc_perm shm_perm;          /* operation permission struct */
> -#if !__SHM_SEGSZ_AFTER_TIME
> -    size_t shm_segsz;                  /* size of segment in bytes */
> -#endif
> -    __SHM_PAD_TIME (shm_atime, 1);     /* time of last shmat() */
> -    __SHM_PAD_TIME (shm_dtime, 2);     /* time of last shmdt() */
> -    __SHM_PAD_TIME (shm_ctime, 3);     /* time of last change by shmctl() */
> -#if __SHM_PAD_BETWEEN_TIME_AND_SEGSZ
> -    unsigned long int __glibc_reserved4;
> -#endif
> -#if __SHM_SEGSZ_AFTER_TIME
> -    size_t shm_segsz;                  /* size of segment in bytes */
> -#endif
> -    __pid_t shm_cpid;                  /* pid of creator */
> -    __pid_t shm_lpid;                  /* pid of last shmop */
> -    shmatt_t shm_nattch;               /* number of current attaches */
> -    __syscall_ulong_t __glibc_reserved5;
> -    __syscall_ulong_t __glibc_reserved6;
> -  };
> +#include <bits/types/struct_shmid_ds.h>
>
>  #ifdef __USE_MISC
>
> diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h
> new file mode 100644
> index 0000000000..938bbedfcd
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/bits/types/struct_shmid_ds.h
> @@ -0,0 +1,57 @@
> +/* Generic implementation of the shared memory struct shmid_ds.
> +   Copyright (C) 2020 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
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#ifndef _SYS_SHM_H
> +# error "Never include <bits/types/struct_shmid_ds.h> directly; use <sys/shm.h> instead."
> +#endif
> +
> +#include <bits/shm-pad.h>
> +
> +#if __SHM_PAD_BEFORE_TIME
> +# define __SHM_PAD_TIME(NAME, RES)                             \
> +  unsigned long int __glibc_reserved ## RES; __time_t NAME
> +#elif __SHM_PAD_AFTER_TIME
> +# define __SHM_PAD_TIME(NAME, RES)                             \
> +  __time_t NAME; unsigned long int __glibc_reserved ## RES
> +#else
> +# define __SHM_PAD_TIME(NAME, RES)             \
> +  __time_t NAME
> +#endif
> +
> +/* Data structure describing a shared memory segment.  */
> +struct shmid_ds
> +  {
> +    struct ipc_perm shm_perm;          /* operation permission struct */
> +#if !__SHM_SEGSZ_AFTER_TIME
> +    size_t shm_segsz;                  /* size of segment in bytes */
> +#endif
> +    __SHM_PAD_TIME (shm_atime, 1);     /* time of last shmat() */
> +    __SHM_PAD_TIME (shm_dtime, 2);     /* time of last shmdt() */
> +    __SHM_PAD_TIME (shm_ctime, 3);     /* time of last change by shmctl() */
> +#if __SHM_PAD_BETWEEN_TIME_AND_SEGSZ
> +    unsigned long int __glibc_reserved4;
> +#endif
> +#if __SHM_SEGSZ_AFTER_TIME
> +    size_t shm_segsz;                  /* size of segment in bytes */
> +#endif
> +    __pid_t shm_cpid;                  /* pid of creator */
> +    __pid_t shm_lpid;                  /* pid of last shmop */
> +    shmatt_t shm_nattch;               /* number of current attaches */
> +    __syscall_ulong_t __glibc_reserved5;
> +    __syscall_ulong_t __glibc_reserved6;
> +  };
> --
> 2.25.1
>
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 7/7] sysv: linux: Add 64-bit time_t variant for shmctl

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
On Wed, Jul 1, 2020 at 4:00 PM Alistair Francis <[hidden email]> wrote:

>
> On Wed, Jul 1, 2020 at 10:07 AM Adhemerval Zanella
> <[hidden email]> wrote:
> >
> >
> >
> > On 01/07/2020 13:35, Adhemerval Zanella wrote:
> > >
> > >
> > > On 01/07/2020 12:48, Alistair Francis wrote:
> > >> On Wed, Jul 1, 2020 at 5:19 AM Adhemerval Zanella
> > >> <[hidden email]> wrote:
> > >>>
> > >>>
> > >>>
> > >>> On 30/06/2020 23:28, Alistair Francis wrote:
> > >>> deps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h b/sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h
> > >>>>> new file mode 100644
> > >>>>> index 0000000000..5533d44dee
> > >>>>> --- /dev/null
> > >>>>> +++ b/sysdeps/unix/sysv/linux/powerpc/struct_kernel_shmid64_ds.h
> > >>>>> @@ -0,0 +1,24 @@
> > >>>>> +/* Analogous to kernel struct shmid64_ds used on shmctl.  */
> > >>>>> +struct kernel_shmid64_ds
> > >>>>> +{
> > >>>>> +  struct ipc_perm shm_perm;
> > >>>>> +#if __TIMESIZE == 64
> > >>>>> +  long int shm_atime;
> > >>>>> +  long int shm_atime;
> > >>>>> +  long int shm_atime;
> > >>>>
> > >>>> This fails to compile as all three variables have the same name.
> > >>>
> > >>> In fact this code specifically is not used on powerpc since it will
> > >>> either use the __TIMESIZE == 32 (powerpc32) or not use this
> > >>> structure at all (powerpc64{le}).  But it is still an issue I will
> > >>> revise the patch for such issues and remove it (maybe adding a
> > >>> #error if it used on powerpc64).
> > >>
> > >> Ah whoops, I commented inline on the wrong file. The generic one
> > >> (sysdeps/unix/sysv/linux/struct_kernel_shmid64_ds.h) also has the same
> > >> problem which is why I saw the RISC-V build fail.
> > >>
> > >>>
> > >>> Besides it, does it work for riscv32 (which should use the default
> > >>> definition)?
> > >>
> > >> This patch doesn't work due to the same name variables in a few places
> > >> (one of them being the generic one).
> > >>
> > >
> > > I need to setup an 32-bit ABI with 64-bit time_t to catch these kind of
> > > issues.
> > >
> > >> I am testing all the other patches and should know by tonight (about 8
> > >> hours still), I'll let you know.
> > >
> > > Ack, you can also do a sniff test with the sysvipc tests to check if
> > > they are ok.
> >
> > Ok, the __TIMESIZE should not be used to define the kernel_* struct anyway,
> > they should be independent of the glibc time ABI selected or defined by
> > the ABI.
> >
> > I have updated my personal branch [1] with an updated version and I will
> > try to check if riscv32 at least built against. If you could also check
> > it would be helpful.
>
> Thanks!
>
> I have tested this series with patch 7 (this patch) dropped and it
> works for RV32.
>
> >
> > [1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/semctl-y2038
>
> I am now running a full test of this branch, unfortunately it'll take
> about 24 hours.

I tested the above branch for RV32 and it passes all the tests, so works for me.

I have also reviewed the current patches on list.

Let me know if I can do anything else to help get this merged.

Alistair

>
> Alistair
123