]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
sysvipc: Set ipc_perm mode as mode_t (BZ#18231)
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Thu, 10 Oct 2019 18:13:11 +0000 (18:13 +0000)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Thu, 10 Oct 2019 20:33:27 +0000 (17:33 -0300)
This patch sets the mode field in ipc_perm as mode_t for all architectures,
as POSIX specification [1].  The changes required are as follow:

  1. It moves the ipc_perm definition out of ipc.h to its own header
     ipc_perm.h.  It also allows consolidate the IPC_* definition on
     only one header.

  2. The generic implementation follow the kernel ipc64_perm size so the
     syscall can be made directly without temporary buffer copy.  However,
     since glibc defines the MODE field as mode_t, it omits the __PAD1 field
     (since glibc does not export mode_t as 16-bit for any architecture).

     It is a two-fold improvement:

     2.1. New implementation which follow Linux UAPI will not need to
  provide an arch-specific ipc-perm.h header neither wrongly
          use the wrong 16-bit definition from previous default ipc.h
  (as csky did).

     2.1. It allows consolidate ipc_perm definition for architectures that
          already provide mode_t as 32-bit.

  3. All kernel ABIs for the supported architectures already provides the
     expected padding for mode type extension to 32-bit.  However, some
     architectures the padding has the wrong placement, so it requires
     the ipc control routines (msgctl, semctl, and shmctl) to adjust the
     mode field accordingly.  Currently they are armeb, microblaze, m68k,
     s390, and sheb.

     A new assume is added, __ASSUME_SYSVIPC_BROKEN_MODE_T, which the
     required ABIs define.

  4. For the ABIs that define __ASSUME_SYSVIPC_BROKEN_MODE_T, it also
     require compat symbols that do not adjust the mode field.

Checked on arm-linux-gnueabihf, aarch64-linux-gnu, powerpc64le-linux-gnu,
and x86_64-linux-gnu. I also checked the sysvipc tests on hppa-linux-gnu,
sh4-linux-gnu, s390x-linux-gnu, and s390-linux-gnu.

I also did a sanity test against armeb qemu usermode for the sysvipc
tests.

[BZ #18231]
* sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add
bits/ipc-perm.h.
* sysdeps/unix/sysv/linux/aarch64/bits/ipc.h: Remove file.
* sysdeps/unix/sysv/linux/alpha/bits/ipc.h: Likewise.
* sysdeps/unix/sysv/linux/hppa/bits/ipc.h: Likewise.
* sysdeps/unix/sysv/linux/ia64/bits/ipc.h: Likewise.
* sysdeps/unix/sysv/linux/mips/bits/ipc.h: Likewise.
* sysdeps/unix/sysv/linux/powerpc/bits/ipc.h: Likewise.
* sysdeps/unix/sysv/linux/s390/bits/ipc.h: Likewise.
* sysdeps/unix/sysv/linux/sparc/bits/ipc.h: Likewise.
* sysdeps/unix/sysv/linux/arm/kernel-features.h
[__BYTE_ORDER == __BIG_ENDIAN] (__ASSUME_SYSVIPC_BROKEN_MODE_T):
Define.
* sysdeps/sysv/linux/microblaze/kernel-features.h: Likewise.
* sysdeps/unix/sysv/linux/s390/kernel-features.h
[!__s390x__] (__ASSUME_SYSVIPC_BROKEN_MODE_T): Define.
* sysdeps/unix/sysv/linux/sh/kernel-features.h
(__ASSUME_SYSVIPC_BROKEN_MODE_T): Define.
* sysdeps/unix/sysv/linux/m68k/kernel-features.h: Likewise.
* sysdeps/unix/sysv/linux/bits/ipc-perm.h: New file.
* sysdeps/unix/sysv/linux/powerpc/bits/ipc-perm.h: Likewise.
* sysdeps/unix/sysv/linux/sparc/bits/ipc-perm.h: Likewise.
* sysdeps/unix/sysv/linux/bits/ipc.h (ipc_perm): Move to
bits/ipc-perm.h.
* sysdeps/unix/sysv/linux/hppa/bits/ipc-perm.h: New file.
* sysdeps/unix/sysv/linux/kernel-features.h: Add comment about
__ASSUME_SYSVIPC_BROKEN_MODE_T semantic.
* sysdeps/unix/sysv/linux/msgctl.c (DEFAULT_VERSION): Define as
2.31 if __ASSUME_SYSVIPC_BROKEN_MODE_T is defined.
(msgctl_syscall, __msgctl_mode16): New symbol.
(__new_msgctl): Add bits for __ASSUME_SYSVIPC_BROKEN_MODE_T.
* sysdeps/unix/sysv/linux/semctl.c: Likewise.
* sysdeps/unix/sysv/linux/shmctl.c: Likewise.
* sysdeps/unix/sysv/linux/arm/be/libc.abilist (GLIBC_2.31): Add
msgctl, semctl, and shmctl.
* sysdeps/sysv/linux/microblaze/be/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/sh/be/libc.abilist: Likewise.
* conform/data/sys/ipc.h-data: Only xfail {struct ipc_perm} mode_t
mode for Hurd.
* sysdeps/unix/sysv/linux/m68k/Versions (libc) [GLIBC_2.31]: Add
msgctl, semctl, and shmctl.
* sysdeps/unix/sysv/linux/arm/be/Versions: New file.
* sysdeps/unix/sysv/linux/microblaze/be/Versions: Likewise.
* sysdeps/unix/sysv/linux/sh/be/Versions: Likewise.

[1] http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_ipc.h.html

34 files changed:
ChangeLog
conform/data/sys/ipc.h-data
sysdeps/unix/sysv/linux/Makefile
sysdeps/unix/sysv/linux/aarch64/bits/ipc.h [deleted file]
sysdeps/unix/sysv/linux/alpha/bits/ipc.h [deleted file]
sysdeps/unix/sysv/linux/arm/be/Versions [new file with mode: 0644]
sysdeps/unix/sysv/linux/arm/be/libc.abilist
sysdeps/unix/sysv/linux/arm/kernel-features.h
sysdeps/unix/sysv/linux/bits/ipc-perm.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/bits/ipc.h
sysdeps/unix/sysv/linux/hppa/bits/ipc-perm.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/hppa/bits/ipc.h [deleted file]
sysdeps/unix/sysv/linux/ia64/bits/ipc.h [deleted file]
sysdeps/unix/sysv/linux/kernel-features.h
sysdeps/unix/sysv/linux/m68k/Versions
sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
sysdeps/unix/sysv/linux/m68k/kernel-features.h
sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
sysdeps/unix/sysv/linux/microblaze/be/Versions [new file with mode: 0644]
sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
sysdeps/unix/sysv/linux/microblaze/kernel-features.h
sysdeps/unix/sysv/linux/mips/bits/ipc.h [deleted file]
sysdeps/unix/sysv/linux/msgctl.c
sysdeps/unix/sysv/linux/powerpc/bits/ipc-perm.h [moved from sysdeps/unix/sysv/linux/powerpc/bits/ipc.h with 63% similarity]
sysdeps/unix/sysv/linux/s390/bits/ipc.h [deleted file]
sysdeps/unix/sysv/linux/s390/kernel-features.h
sysdeps/unix/sysv/linux/s390/s390-32/Versions
sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
sysdeps/unix/sysv/linux/semctl.c
sysdeps/unix/sysv/linux/sh/be/Versions [new file with mode: 0644]
sysdeps/unix/sysv/linux/sh/be/libc.abilist
sysdeps/unix/sysv/linux/sh/kernel-features.h
sysdeps/unix/sysv/linux/shmctl.c
sysdeps/unix/sysv/linux/sparc/bits/ipc-perm.h [moved from sysdeps/unix/sysv/linux/sparc/bits/ipc.h with 59% similarity]

index 53ae72288fb0506a88e06426f79cb0b415df4117..6bf3462b5834a75db9afde9f9a7f78f160f70eca 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,54 @@
+2019-10-10  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+       [BZ #18231]
+       * sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add
+       bits/ipc-perm.h.
+       * sysdeps/unix/sysv/linux/aarch64/bits/ipc.h: Remove file.
+       * sysdeps/unix/sysv/linux/alpha/bits/ipc.h: Likewise.
+       * sysdeps/unix/sysv/linux/hppa/bits/ipc.h: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/bits/ipc.h: Likewise.
+       * sysdeps/unix/sysv/linux/mips/bits/ipc.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/bits/ipc.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/bits/ipc.h: Likewise.
+       * sysdeps/unix/sysv/linux/sparc/bits/ipc.h: Likewise.
+       * sysdeps/unix/sysv/linux/arm/kernel-features.h
+       [__BYTE_ORDER == __BIG_ENDIAN] (__ASSUME_SYSVIPC_BROKEN_MODE_T):
+       Define.
+       * sysdeps/sysv/linux/microblaze/kernel-features.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/kernel-features.h
+       [!__s390x__] (__ASSUME_SYSVIPC_BROKEN_MODE_T): Define.
+       * sysdeps/unix/sysv/linux/sh/kernel-features.h
+       (__ASSUME_SYSVIPC_BROKEN_MODE_T): Define.
+       * sysdeps/unix/sysv/linux/m68k/kernel-features.h: Likewise.
+       * sysdeps/unix/sysv/linux/bits/ipc-perm.h: New file.
+       * sysdeps/unix/sysv/linux/powerpc/bits/ipc-perm.h: Likewise.
+       * sysdeps/unix/sysv/linux/sparc/bits/ipc-perm.h: Likewise.
+       * sysdeps/unix/sysv/linux/bits/ipc.h (ipc_perm): Move to
+       bits/ipc-perm.h.
+       * sysdeps/unix/sysv/linux/hppa/bits/ipc-perm.h: New file.
+       * sysdeps/unix/sysv/linux/kernel-features.h: Add comment about
+       __ASSUME_SYSVIPC_BROKEN_MODE_T semantic.
+       * sysdeps/unix/sysv/linux/msgctl.c (DEFAULT_VERSION): Define as
+       2.31 if __ASSUME_SYSVIPC_BROKEN_MODE_T is defined.
+       (msgctl_syscall, __msgctl_mode16): New symbol.
+       (__new_msgctl): Add bits for __ASSUME_SYSVIPC_BROKEN_MODE_T.
+       * sysdeps/unix/sysv/linux/semctl.c: Likewise.
+       * sysdeps/unix/sysv/linux/shmctl.c: Likewise.
+       * sysdeps/unix/sysv/linux/arm/be/libc.abilist (GLIBC_2.31): Add
+       msgctl, semctl, and shmctl.
+       * sysdeps/sysv/linux/microblaze/be/libc.abilist: Likewise.
+       * sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist: Likewise.
+       * sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist: Likewise.
+       * sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist: Likewise.
+       * sysdeps/unix/sysv/linux/sh/be/libc.abilist: Likewise.
+       * conform/data/sys/ipc.h-data: Only xfail {struct ipc_perm} mode_t
+       mode for Hurd.
+       * sysdeps/unix/sysv/linux/m68k/Versions (libc) [GLIBC_2.31]: Add
+       msgctl, semctl, and shmctl.
+       * sysdeps/unix/sysv/linux/arm/be/Versions: New file.
+       * sysdeps/unix/sysv/linux/microblaze/be/Versions: Likewise.
+       * sysdeps/unix/sysv/linux/sh/be/Versions: Likewise.
+
 2019-10-10  Andreas Schwab  <schwab@suse.de>
 
        * elf/dl-load.c (open_verify): Remove dead code.
index 09e8f68f8e2f6b0f799f98bdd32a85a3f0de4d4d..1364b07e87e5a085d9061c0c3b91d7a7d53c7328 100644 (file)
@@ -6,8 +6,7 @@ xfail[i386-gnu]-element {struct ipc_perm} uid_t uid
 xfail[i386-gnu]-element {struct ipc_perm} gid_t gid
 xfail[i386-gnu]-element {struct ipc_perm} uid_t cuid
 xfail[i386-gnu]-element {struct ipc_perm} gid_t cgid
-// Bug 18231: wrong type for mode member.
-xfail-element {struct ipc_perm} mode_t mode
+xfail[i386-gnu]-element {struct ipc_perm} mode_t mode
 
 type uid_t
 type gid_t
index 7203581e2fac364b9c3570b492c226dc3cbf75a2..0e09d61a7a2b7d168a6079a6cdf3bef677f6156e 100644 (file)
@@ -48,7 +48,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
                  bits/termios-c_iflag.h bits/termios-c_oflag.h \
                  bits/termios-baud.h bits/termios-c_cflag.h \
                  bits/termios-c_lflag.h bits/termios-tcflow.h \
-                 bits/termios-misc.h
+                 bits/termios-misc.h \
+                 bits/ipc-perm.h
 
 tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
         tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/ipc.h b/sysdeps/unix/sysv/linux/aarch64/bits/ipc.h
deleted file mode 100644 (file)
index a58c898..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright (C) 1995-2019 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_IPC_H
-# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
-#endif
-
-#include <bits/types.h>
-
-/* Mode bits for `msgget', `semget', and `shmget'.  */
-#define IPC_CREAT      01000           /* Create key if key does not exist. */
-#define IPC_EXCL       02000           /* Fail if key exists.  */
-#define IPC_NOWAIT     04000           /* Return error on wait.  */
-
-/* Control commands for `msgctl', `semctl', and `shmctl'.  */
-#define IPC_RMID       0               /* Remove identifier.  */
-#define IPC_SET                1               /* Set `ipc_perm' options.  */
-#define IPC_STAT       2               /* Get `ipc_perm' options.  */
-#ifdef __USE_GNU
-# define IPC_INFO      3               /* See ipcs.  */
-#endif
-
-/* Special key values.  */
-#define IPC_PRIVATE    ((__key_t) 0)   /* Private key.  */
-
-
-/* Data structure used to pass permission information to IPC operations.  */
-struct ipc_perm
-  {
-    __key_t __key;                     /* Key.  */
-    __uid_t uid;                       /* Owner's user ID.  */
-    __gid_t gid;                       /* Owner's group ID.  */
-    __uid_t cuid;                      /* Creator's user ID.  */
-    __gid_t cgid;                      /* Creator's group ID.  */
-    unsigned int mode;                 /* Read/write permission.  */
-    unsigned short int __seq;          /* Sequence number.  */
-    unsigned short int __pad1;
-    __syscall_ulong_t __glibc_reserved1;
-    __syscall_ulong_t __glibc_reserved2;
-  };
diff --git a/sysdeps/unix/sysv/linux/alpha/bits/ipc.h b/sysdeps/unix/sysv/linux/alpha/bits/ipc.h
deleted file mode 100644 (file)
index 71cf2d5..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright (C) 1995-2019 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_IPC_H
-# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
-#endif
-
-#include <bits/types.h>
-
-/* Mode bits for `msgget', `semget', and `shmget'.  */
-#define IPC_CREAT      01000           /* Create key if key does not exist. */
-#define IPC_EXCL       02000           /* Fail if key exists.  */
-#define IPC_NOWAIT     04000           /* Return error on wait.  */
-
-/* Control commands for `msgctl', `semctl', and `shmctl'.  */
-#define IPC_RMID       0               /* Remove identifier.  */
-#define IPC_SET                1               /* Set `ipc_perm' options.  */
-#define IPC_STAT       2               /* Get `ipc_perm' options.  */
-#ifdef __USE_GNU
-# define IPC_INFO      3               /* See ipcs.  */
-#endif
-
-/* Special key values.  */
-#define IPC_PRIVATE    ((__key_t) 0)   /* Private key.  */
-
-
-/* Data structure used to pass permission information to IPC operations.  */
-struct ipc_perm
-  {
-    __key_t __key;                     /* Key.  */
-    unsigned int uid;                  /* Owner's user ID.  */
-    unsigned int gid;                  /* Owner's group ID.  */
-    unsigned int cuid;                 /* Creator's user ID.  */
-    unsigned int cgid;                 /* Creator's group ID.  */
-    unsigned int mode;                 /* Read/write permission.  */
-    unsigned short int __seq;          /* Sequence number.  */
-    unsigned short int __pad1;
-    unsigned long int __glibc_reserved1;
-    unsigned long int __glibc_reserved2;
-  };
diff --git a/sysdeps/unix/sysv/linux/arm/be/Versions b/sysdeps/unix/sysv/linux/arm/be/Versions
new file mode 100644 (file)
index 0000000..a50cd57
--- /dev/null
@@ -0,0 +1,5 @@
+libc {
+  GLIBC_2.31 {
+    msgctl; semctl; shmctl;
+  }
+}
index 9371927927093d6f2e6a21ae558d32ab04cf484c..b152c0e24a24c6cf4ac9196a0c2b4a3613e8e51c 100644 (file)
@@ -130,6 +130,9 @@ GLIBC_2.30 getdents64 F
 GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
+GLIBC_2.31 msgctl F
+GLIBC_2.31 semctl F
+GLIBC_2.31 shmctl F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
index 3befa92b57dfa55c7907e554eadb729fd2ff6f12..6b32970e2b18c3b2eacd05436c0ddc866b75b162 100644 (file)
@@ -17,6 +17,7 @@
    License along with the GNU C Library.  If not, see
    <https://www.gnu.org/licenses/>.  */
 
+#include <endian.h>
 #include_next <kernel-features.h>
 
 /* The ARM kernel before 3.14.3 may or may not support
@@ -49,3 +50,7 @@
 
 #undef __ASSUME_CLONE_DEFAULT
 #define __ASSUME_CLONE_BACKWARDS       1
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+# define __ASSUME_SYSVIPC_BROKEN_MODE_T
+#endif
diff --git a/sysdeps/unix/sysv/linux/bits/ipc-perm.h b/sysdeps/unix/sysv/linux/bits/ipc-perm.h
new file mode 100644 (file)
index 0000000..2c3f49f
--- /dev/null
@@ -0,0 +1,40 @@
+/* struct ipc_perm definition.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_IPC_H
+# error "Never use <bits/ipc-perm.h> directly; include <sys/ipc.h> instead."
+#endif
+
+/* Data structure used to pass permission information to IPC operations.
+   It follows the kernel ipc64_perm size so the syscall can be made directly
+   without temporary buffer copy.  However, since glibc defines the MODE
+   field as mode_t per POSIX definition (BZ#18231), it omits the __PAD1 field
+   (since glibc does not export mode_t as 16-bit for any architecture).  */
+struct ipc_perm
+{
+  __key_t __key;                               /* Key.  */
+  __uid_t uid;                                 /* Owner's user ID.  */
+  __gid_t gid;                                 /* Owner's group ID.  */
+  __uid_t cuid;                                        /* Creator's user ID.  */
+  __gid_t cgid;                                        /* Creator's group ID.  */
+  __mode_t mode;                               /* Read/write permission.  */
+  unsigned short int __seq;                    /* Sequence number.  */
+  unsigned short int __pad2;
+  __syscall_ulong_t __glibc_reserved1;
+  __syscall_ulong_t __glibc_reserved2;
+};
index 652369cb8d4eac087ceff301b389a1c062b197e0..9939857ab5a76ab768ec207b77a240e260403b2a 100644 (file)
 /* Special key values.  */
 #define IPC_PRIVATE    ((__key_t) 0)   /* Private key.  */
 
-
-/* Data structure used to pass permission information to IPC operations.  */
-struct ipc_perm
-  {
-    __key_t __key;                     /* Key.  */
-    __uid_t uid;                       /* Owner's user ID.  */
-    __gid_t gid;                       /* Owner's group ID.  */
-    __uid_t cuid;                      /* Creator's user ID.  */
-    __gid_t cgid;                      /* Creator's group ID.  */
-    unsigned short int mode;           /* Read/write permission.  */
-    unsigned short int __pad1;
-    unsigned short int __seq;          /* Sequence number.  */
-    unsigned short int __pad2;
-    __syscall_ulong_t __glibc_reserved1;
-    __syscall_ulong_t __glibc_reserved2;
-  };
+#include <bits/ipc-perm.h>
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/ipc-perm.h b/sysdeps/unix/sysv/linux/hppa/bits/ipc-perm.h
new file mode 100644 (file)
index 0000000..f29fc16
--- /dev/null
@@ -0,0 +1,37 @@
+/* struct ipc_perm definition.
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_IPC_H
+# error "Never use <bits/ipc-perm.h> directly; include <sys/ipc.h> instead."
+#endif
+
+/* Data structure used to pass permission information to IPC operations.  */
+struct ipc_perm
+  {
+    __key_t __key;                      /* Key.  */
+    __uid_t uid;                        /* Owner's user ID.  */
+    __gid_t gid;                        /* Owner's group ID.  */
+    __uid_t cuid;                       /* Creator's user ID.  */
+    __gid_t cgid;                       /* Creator's group ID.  */
+    __mode_t mode;                      /* Read/write permission.  */
+    unsigned short int __pad2;
+    unsigned short int __seq;           /* Sequence number.  */
+    unsigned int __pad3;
+    __extension__ unsigned long long int __glibc_reserved1;
+    __extension__ unsigned long long int __glibc_reserved2;
+  };
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/ipc.h b/sysdeps/unix/sysv/linux/hppa/bits/ipc.h
deleted file mode 100644 (file)
index b7ae38d..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Copyright (C) 1995-2019 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_IPC_H
-# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
-#endif
-
-#include <bits/types.h>
-#include <bits/wordsize.h>
-
-/* Mode bits for `msgget', `semget', and `shmget'.  */
-#define IPC_CREAT      01000           /* Create key if key does not exist. */
-#define IPC_EXCL       02000           /* Fail if key exists.  */
-#define IPC_NOWAIT     04000           /* Return error on wait.  */
-
-/* Control commands for `msgctl', `semctl', and `shmctl'.  */
-#define IPC_RMID       0               /* Remove identifier.  */
-#define IPC_SET                1               /* Set `ipc_perm' options.  */
-#define IPC_STAT       2               /* Get `ipc_perm' options.  */
-#ifdef __USE_GNU
-# define IPC_INFO      3               /* See ipcs.  */
-#endif
-
-/* Special key values.  */
-#define IPC_PRIVATE    ((__key_t) 0)   /* Private key.  */
-
-
-/* Data structure used to pass permission information to IPC operations.  */
-struct ipc_perm
-  {
-    __key_t __key;                     /* Key.  */
-    __uid_t uid;                       /* Owner's user ID.  */
-    __gid_t gid;                       /* Owner's group ID.  */
-    __uid_t cuid;                      /* Creator's user ID.  */
-    __gid_t cgid;                      /* Creator's group ID.  */
-#if __WORDSIZE == 32
-    unsigned short int __pad1;
-    unsigned short int mode;           /* Read/write permission.  */
-    unsigned short int __pad2;
-#else
-    __mode_t mode;                     /* Read/write permission.  */
-    unsigned short int __pad2;
-#endif
-    unsigned short int __seq;          /* Sequence number.  */
-    unsigned int __pad3;
-    __extension__ unsigned long long int __glibc_reserved1;
-    __extension__ unsigned long long int __glibc_reserved2;
-  };
diff --git a/sysdeps/unix/sysv/linux/ia64/bits/ipc.h b/sysdeps/unix/sysv/linux/ia64/bits/ipc.h
deleted file mode 100644 (file)
index 2d7a920..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Copyright (C) 2000-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-       Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
-
-   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_IPC_H
-# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
-#endif
-
-#include <sys/types.h>
-
-/* Mode bits for `msgget', `semget', and `shmget'.  */
-#define IPC_CREAT      01000           /* Create key if key does not exist. */
-#define IPC_EXCL       02000           /* Fail if key exists.  */
-#define IPC_NOWAIT     04000           /* Return error on wait.  */
-
-/* Control commands for `msgctl', `semctl', and `shmctl'.  */
-#define IPC_RMID       0               /* Remove identifier.  */
-#define IPC_SET                1               /* Set `ipc_perm' options.  */
-#define IPC_STAT       2               /* Get `ipc_perm' options.  */
-#define IPC_INFO       3               /* See ipcs.  */
-
-/* Special key values.  */
-#define IPC_PRIVATE    ((__key_t) 0)   /* Private key.  */
-
-
-/* Data structure used to pass permission information to IPC operations.  */
-struct ipc_perm
-  {
-    __key_t __key;                     /* Key.  */
-    __uid_t uid;                       /* Owner's user ID.  */
-    __gid_t gid;                       /* Owner's group ID.  */
-    __uid_t cuid;                      /* Creator's user ID.  */
-    __gid_t cgid;                      /* Creator's group ID.  */
-    __mode_t mode;                     /* Read/write permission.  */
-    unsigned short int __seq;          /* Sequence number.  */
-    unsigned short int __pad1;
-    unsigned long int __glibc_reserved1;
-    unsigned long int __glibc_reserved2;
-  };
index 5b35722768026165bc72c22bf6ef70a7d04bdb7b..7305686081b9c8eca368494c92f5c86b4cb541dc 100644 (file)
    either support ipc syscall and/or all the ipc correspondent syscalls.  */
 #define __ASSUME_DIRECT_SYSVIPC_SYSCALLS       1
 
+/* All supported architectures reserve a 32-bit for MODE field in sysvipc
+   ipc_perm.  However, some kernel ABI interfaces still expect a 16-bit
+   field.  This is only an issue if arch-defined IPC_PERM padding is on a
+   wrong position regarding endianness.  In this case, the IPC control
+   routines (msgctl, semctl, and semtctl) requires to shift the value to
+   correct place.
+   The ABIs that requires it define __ASSUME_SYSVIPC_BROKEN_MODE_T.  */
+
 /* Support for p{read,write}v2 was added in 4.6.  However Linux default
    implementation does not assume the __ASSUME_* and instead use a fallback
    implementation based on p{read,write}v and returning an error for
index 8e72cd18cb5fb55ec3efdf53705bdf7d65e2db08..4b187955139e02599ffb3cc96cfb076ff6ee6092 100644 (file)
@@ -37,6 +37,9 @@ libc {
   GLIBC_2.11 {
     fallocate64;
   }
+  GLIBC_2.31 {
+    msgctl; semctl; shmctl;
+  }
   GLIBC_2.12 {
     __m68k_read_tp;
   }
index f3aa47d09022e1a45ae2ee7703d7fcb3565cd966..5e3cdea24688db21884281b5779a842d57245abb 100644 (file)
@@ -131,6 +131,9 @@ GLIBC_2.30 getdents64 F
 GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
+GLIBC_2.31 msgctl F
+GLIBC_2.31 semctl F
+GLIBC_2.31 shmctl F
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0x98
 GLIBC_2.4 _IO_2_1_stdin_ D 0x98
index fe9a5b3e8877fe15081dd4bfc083c897614f0cb1..becc05d4dd8fc20b218737863ba64a88d85c3f6b 100644 (file)
@@ -52,3 +52,4 @@
 
 /* m68k only supports ipc syscall.  */
 #undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
+#define __ASSUME_SYSVIPC_BROKEN_MODE_T
index 64d4623b6b14bd1a2d8e921f9fe2ffae4e9e4532..ea5e7a41afde31e3d266c2a03cb477d6756fe08a 100644 (file)
@@ -2155,6 +2155,9 @@ GLIBC_2.30 getdents64 F
 GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
+GLIBC_2.31 msgctl F
+GLIBC_2.31 semctl F
+GLIBC_2.31 shmctl F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/Versions b/sysdeps/unix/sysv/linux/microblaze/be/Versions
new file mode 100644 (file)
index 0000000..a50cd57
--- /dev/null
@@ -0,0 +1,5 @@
+libc {
+  GLIBC_2.31 {
+    msgctl; semctl; shmctl;
+  }
+}
index f7ced487f78f878ca54518b1ddeedc3bf57bd6e1..ac55b0acd7de44b6047dcb1d3907dff7bb8046a9 100644 (file)
@@ -2137,3 +2137,6 @@ GLIBC_2.30 getdents64 F
 GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
+GLIBC_2.31 msgctl F
+GLIBC_2.31 semctl F
+GLIBC_2.31 shmctl F
index 79102079cd17edcbcb110f393daa19ad98d4c80d..19c77a42bd2054b62e09b52c9e00db5c1d3f3185 100644 (file)
@@ -15,6 +15,7 @@
    License along with the GNU C Library.  If not, see
    <https://www.gnu.org/licenses/>.  */
 
+#include <endian.h>
 
 /* All supported kernel versions for MicroBlaze have these syscalls.  */
 #define __ASSUME_SOCKET_SYSCALL                1
@@ -67,3 +68,7 @@
 
 #undef __ASSUME_CLONE_DEFAULT
 #define __ASSUME_CLONE_BACKWARDS3
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+# define __ASSUME_SYSVIPC_BROKEN_MODE_T
+#endif
diff --git a/sysdeps/unix/sysv/linux/mips/bits/ipc.h b/sysdeps/unix/sysv/linux/mips/bits/ipc.h
deleted file mode 100644 (file)
index 465bc42..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright (C) 1995-2019 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_IPC_H
-# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
-#endif
-
-#include <bits/types.h>
-
-/* Mode bits for `msgget', `semget', and `shmget'.  */
-#define IPC_CREAT      01000           /* Create key if key does not exist. */
-#define IPC_EXCL       02000           /* Fail if key exists.  */
-#define IPC_NOWAIT     04000           /* Return error on wait.  */
-
-/* Control commands for `msgctl', `semctl', and `shmctl'.  */
-#define IPC_RMID       0               /* Remove identifier.  */
-#define IPC_SET                1               /* Set `ipc_perm' options.  */
-#define IPC_STAT       2               /* Get `ipc_perm' options.  */
-#ifdef __USE_GNU
-# define IPC_INFO      3               /* See ipcs.  */
-#endif
-
-/* Special key values. */
-#define IPC_PRIVATE    ((__key_t) 0)   /* Private key.  */
-
-
-/* Data structure used to pass permission information to IPC operations.  */
-struct ipc_perm
-  {
-    __key_t __key;                     /* Key.  */
-    unsigned int uid;                  /* Owner's user ID.  */
-    unsigned int gid;                  /* Owner's group ID.  */
-    unsigned int cuid;                 /* Creator's user ID.  */
-    unsigned int cgid;                 /* Creator's group ID.  */
-    unsigned int mode;                 /* Read/write permission.  */
-    unsigned short int __seq;          /* Sequence number.  */
-    unsigned short int __pad1;
-    unsigned long int __glibc_reserved1;
-    unsigned long int __glibc_reserved2;
-};
index a52b5477ce66e48dcd757186bb27b81aa609ee5d..19d5ded19f57db772e12838a9ebb4dfb1331b167 100644 (file)
 #include <errno.h>
 
 #ifndef DEFAULT_VERSION
-# define DEFAULT_VERSION GLIBC_2_2
+# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T
+#  define DEFAULT_VERSION GLIBC_2_2
+# else
+#  define DEFAULT_VERSION GLIBC_2_31
+# endif
 #endif
 
-int
-__new_msgctl (int msqid, int cmd, struct msqid_ds *buf)
+static int
+msgctl_syscall (int msqid, int cmd, struct msqid_ds *buf)
 {
 #ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
   return INLINE_SYSCALL_CALL (msgctl, msqid, cmd | __IPC_64, buf);
@@ -36,8 +40,54 @@ __new_msgctl (int msqid, int cmd, struct msqid_ds *buf)
                              buf);
 #endif
 }
+
+int
+__new_msgctl (int msqid, int cmd, struct msqid_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)
+    {
+      tmpds = *buf;
+      tmpds.msg_perm.mode *= 0x10000U;
+      buf = &tmpds;
+    }
+#endif
+
+  int ret = msgctl_syscall (msqid, cmd, buf);
+
+#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
+  if (ret >= 0)
+    {
+      switch (cmd)
+       {
+       case IPC_STAT:
+       case MSG_STAT:
+       case MSG_STAT_ANY:
+         buf->msg_perm.mode >>= 16;
+       }
+    }
+#endif
+
+  return ret;
+}
 versioned_symbol (libc, __new_msgctl, msgctl, DEFAULT_VERSION);
 
+#if defined __ASSUME_SYSVIPC_BROKEN_MODE_T \
+    && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_31)
+int
+attribute_compat_text_section
+__msgctl_mode16 (int msqid, int cmd, struct msqid_ds *buf)
+{
+  return msgctl_syscall (msqid, cmd, buf);
+}
+compat_symbol (libc, __msgctl_mode16, msgctl, GLIBC_2_2);
+#endif
 
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
 struct __old_msqid_ds
similarity index 63%
rename from sysdeps/unix/sysv/linux/powerpc/bits/ipc.h
rename to sysdeps/unix/sysv/linux/powerpc/bits/ipc-perm.h
index 73854061278c5ce392555df88308bbd940d98285..959ea32993a7c0133899584a5f7490146f28e79a 100644 (file)
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995-2019 Free Software Foundation, Inc.
+/* struct ipc_perm definition.  Linux/powerpc version.
+   Copyright (C) 1995-2019 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
    <https://www.gnu.org/licenses/>.  */
 
 #ifndef _SYS_IPC_H
-# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
+# error "Never use <bits/ipc-perm.h> directly; include <sys/ipc.h> instead."
 #endif
 
-#include <bits/types.h>
-
-/* Mode bits for `msgget', `semget', and `shmget'.  */
-#define IPC_CREAT      01000           /* Create key if key does not exist. */
-#define IPC_EXCL       02000           /* Fail if key exists.  */
-#define IPC_NOWAIT     04000           /* Return error on wait.  */
-
-/* Control commands for `msgctl', `semctl', and `shmctl'.  */
-#define IPC_RMID       0               /* Remove identifier.  */
-#define IPC_SET                1               /* Set `ipc_perm' options.  */
-#define IPC_STAT       2               /* Get `ipc_perm' options.  */
-#ifdef __USE_GNU
-# define IPC_INFO      3               /* See ipcs.  */
-#endif
-
-/* Special key values.  */
-#define IPC_PRIVATE    ((__key_t) 0)   /* Private key.  */
-
-
 /* Data structure used to pass permission information to IPC operations.  */
 struct ipc_perm
   {
diff --git a/sysdeps/unix/sysv/linux/s390/bits/ipc.h b/sysdeps/unix/sysv/linux/s390/bits/ipc.h
deleted file mode 100644 (file)
index d4dd567..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright (C) 2001-2019 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_IPC_H
-# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
-#endif
-
-#include <bits/types.h>
-#include <bits/wordsize.h>
-
-/* Mode bits for `msgget', `semget', and `shmget'.  */
-#define IPC_CREAT      01000           /* Create key if key does not exist. */
-#define IPC_EXCL       02000           /* Fail if key exists.  */
-#define IPC_NOWAIT     04000           /* Return error on wait.  */
-
-/* Control commands for `msgctl', `semctl', and `shmctl'.  */
-#define IPC_RMID       0               /* Remove identifier.  */
-#define IPC_SET                1               /* Set `ipc_perm' options.  */
-#define IPC_STAT       2               /* Get `ipc_perm' options.  */
-#ifdef __USE_GNU
-#define IPC_INFO       3               /* See ipcs.  */
-#endif
-
-/* Special key values. */
-#define IPC_PRIVATE    ((__key_t) 0)   /* Private key.  */
-
-
-/* Data structure used to pass permission information to IPC operations.  */
-struct ipc_perm
-  {
-    __key_t __key;                     /* Key.  */
-    __uid_t uid;                       /* Owner's user ID.  */
-    __gid_t gid;                       /* Owner's group ID.  */
-    __uid_t cuid;                      /* Creator's user ID.  */
-    __gid_t cgid;                      /* Creator's group ID.  */
-#if __WORDSIZE == 64
-    __mode_t mode;                     /* Read/write permission.  */
-#else
-    unsigned short int mode;           /* Read/write permission.  */
-    unsigned short int __pad1;
-#endif
-    unsigned short int __seq;          /* Sequence number.  */
-    unsigned short int __pad2;
-    unsigned long int __glibc_reserved1;
-    unsigned long int __glibc_reserved2;
-  };
index 7e7437df5c2bb52a055e9763f92c1fb54df8fdea..6dca32c6c77abfe302b55053b96c15246fe797f9 100644 (file)
@@ -47,6 +47,9 @@
 
 /* s390 only supports ipc syscall.  */
 #undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
+#ifndef __s390x__
+# define __ASSUME_SYSVIPC_BROKEN_MODE_T
+#endif
 
 #undef __ASSUME_CLONE_DEFAULT
 #define __ASSUME_CLONE_BACKWARDS2
index 1c120e8cbeabd8d13bb799252b799a799812d8de..99193982a700308c610a7e8a20ea5a1d9b8c8031 100644 (file)
@@ -49,6 +49,9 @@ libc {
   GLIBC_2.11 {
     fallocate64;
   }
+  GLIBC_2.31 {
+    msgctl; semctl; shmctl;
+  }
 }
 
 libutil {
index 122d0fb65a53ff227fd3eaccf134753cf1ad444f..4feca641b0333b25fb902cbac298f9418f6dd753 100644 (file)
@@ -2180,6 +2180,9 @@ GLIBC_2.30 getdents64 F
 GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
+GLIBC_2.31 msgctl F
+GLIBC_2.31 semctl F
+GLIBC_2.31 shmctl F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
index fbe4b4f11facf92afa707a73c5249cdd941ca5fd..e7f48e4093a86ab46316a4d0d8ae90d0bc5c19a5 100644 (file)
@@ -33,12 +33,33 @@ union semun
 };
 
 #ifndef DEFAULT_VERSION
-# define DEFAULT_VERSION GLIBC_2_2
+# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T
+#  define DEFAULT_VERSION GLIBC_2_2
+# else
+#  define DEFAULT_VERSION GLIBC_2_31
+# endif
 #endif
 
+static int
+semctl_syscall (int semid, int semnum, int cmd, union semun arg)
+{
+#ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
+  return INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd | __IPC_64,
+                             arg.array);
+#else
+  return INLINE_SYSCALL_CALL (ipc, IPCOP_semctl, semid, semnum, cmd | __IPC_64,
+                             SEMCTL_ARG_ADDRESS (arg));
+#endif
+}
+
 int
 __new_semctl (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 };
   va_list ap;
 
@@ -59,16 +80,65 @@ __new_semctl (int semid, int semnum, int cmd, ...)
       break;
     }
 
-#ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
-  return INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd | __IPC_64,
-                             arg.array);
-#else
-  return INLINE_SYSCALL_CALL (ipc, IPCOP_semctl, semid, semnum, cmd | __IPC_64,
-                             SEMCTL_ARG_ADDRESS (arg));
+#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;
+    }
+#endif
+
+  int ret = semctl_syscall (semid, semnum, cmd, arg);
+
+#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
+  if (ret >= 0)
+    {
+      switch (cmd)
+       {
+        case IPC_STAT:
+        case SEM_STAT:
+        case SEM_STAT_ANY:
+          arg.buf->sem_perm.mode >>= 16;
+       }
+    }
 #endif
+
+  return ret;
 }
 versioned_symbol (libc, __new_semctl, semctl, DEFAULT_VERSION);
 
+#if defined __ASSUME_SYSVIPC_BROKEN_MODE_T \
+    && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_31)
+int
+attribute_compat_text_section
+__semctl_mode16 (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;
+    }
+
+  return semctl_syscall (semid, semnum, cmd, arg);
+}
+compat_symbol (libc, __semctl_mode16, semctl, GLIBC_2_2);
+#endif
 
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
 /* Since semctl use a variadic argument for semid_ds there is not need to
diff --git a/sysdeps/unix/sysv/linux/sh/be/Versions b/sysdeps/unix/sysv/linux/sh/be/Versions
new file mode 100644 (file)
index 0000000..a50cd57
--- /dev/null
@@ -0,0 +1,5 @@
+libc {
+  GLIBC_2.31 {
+    msgctl; semctl; shmctl;
+  }
+}
index 4b057bf4a2d2dce34a85614b06121d7ce7d9a349..6bfc2b7439c0299900e27c852e9a719b5b0f008a 100644 (file)
@@ -2050,6 +2050,9 @@ GLIBC_2.30 getdents64 F
 GLIBC_2.30 gettid F
 GLIBC_2.30 tgkill F
 GLIBC_2.30 twalk_r F
+GLIBC_2.31 msgctl F
+GLIBC_2.31 semctl F
+GLIBC_2.31 shmctl F
 GLIBC_2.4 __confstr_chk F
 GLIBC_2.4 __fgets_chk F
 GLIBC_2.4 __fgets_unlocked_chk F
index 80fd7a8a4e148dc7e8ef16a05358e1b8d68f1e30..fae54c8df5dd703d5a53bdc1ae002414aea4daf3 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef __KERNEL_FEATURES_SH__
 # define __KERNEL_FEATURES_SH__
 
+#include <endian.h>
+
 /* These syscalls were added for SH in 2.6.37.  */
 #define __ASSUME_SOCKET_SYSCALL                1
 #define __ASSUME_BIND_SYSCALL          1
@@ -43,6 +45,9 @@
 
 /* sh only supports ipc syscall.  */
 #undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
+#if __BYTE_ORDER == __BIG_ENDIAN
+# define __ASSUME_SYSVIPC_BROKEN_MODE_T
+#endif
 
 /* Support for several syscalls was added in 4.8.  */
 #if __LINUX_KERNEL_VERSION < 0x040800
index 281fd13bb44a7589d9072a489be9ac31b3bf0513..606c8dcd6b640953f3fcba045f4dcf7029c500be 100644 (file)
 #include <shlib-compat.h>
 #include <errno.h>
 
-
 #ifndef DEFAULT_VERSION
-# define DEFAULT_VERSION GLIBC_2_2
+# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T
+#  define DEFAULT_VERSION GLIBC_2_2
+# else
+#  define DEFAULT_VERSION GLIBC_2_31
+# endif
 #endif
 
-
-/* Provide operations to control over shared memory segments.  */
-int
-__new_shmctl (int shmid, int cmd, struct shmid_ds *buf)
+static int
+shmctl_syscall (int shmid, int cmd, struct shmid_ds *buf)
 {
 #ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
   return INLINE_SYSCALL_CALL (shmctl, shmid, cmd | __IPC_64, buf);
@@ -40,8 +41,55 @@ __new_shmctl (int shmid, int cmd, struct shmid_ds *buf)
                              buf);
 #endif
 }
+
+/* Provide operations to control over shared memory segments.  */
+int
+__new_shmctl (int shmid, int cmd, struct shmid_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)
+    {
+      tmpds = *buf;
+      tmpds.shm_perm.mode *= 0x10000U;
+      buf = &tmpds;
+    }
+#endif
+
+  int ret = shmctl_syscall (shmid, cmd, buf);
+
+#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
+  if (ret >= 0)
+    {
+      switch (cmd)
+       {
+        case IPC_STAT:
+        case SHM_STAT:
+        case SHM_STAT_ANY:
+          buf->shm_perm.mode >>= 16;
+       }
+    }
+#endif
+
+  return ret;
+}
 versioned_symbol (libc, __new_shmctl, shmctl, DEFAULT_VERSION);
 
+#if defined __ASSUME_SYSVIPC_BROKEN_MODE_T \
+    && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_31)
+int
+attribute_compat_text_section
+__shmctl_mode16 (int shmid, int cmd, struct shmid_ds *buf)
+{
+  return shmctl_syscall (shmid, cmd, buf);
+}
+compat_symbol (libc, __shmctl_mode16, shmctl, GLIBC_2_2);
+#endif
 
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
 struct __old_shmid_ds
similarity index 59%
rename from sysdeps/unix/sysv/linux/sparc/bits/ipc.h
rename to sysdeps/unix/sysv/linux/sparc/bits/ipc-perm.h
index 9d290a6b82900fe1750913a2844a57e1d7ab3284..e57f50c3306f446ec12525e8dc931cd668735626 100644 (file)
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995-2019 Free Software Foundation, Inc.
+/* struct ipc_perm definition.  Linux/sparc version.
+   Copyright (C) 1995-2019 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
    <https://www.gnu.org/licenses/>.  */
 
 #ifndef _SYS_IPC_H
-# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
+# error "Never use <bits/ipc-perm.h> directly; include <sys/ipc.h> instead."
 #endif
 
-#include <bits/types.h>
-#include <bits/wordsize.h>
-
-/* Mode bits for `msgget', `semget', and `shmget'.  */
-#define IPC_CREAT      01000           /* Create key if key does not exist. */
-#define IPC_EXCL       02000           /* Fail if key exists.  */
-#define IPC_NOWAIT     04000           /* Return error on wait.  */
-
-/* Control commands for `msgctl', `semctl', and `shmctl'.  */
-#define IPC_RMID       0               /* Remove identifier.  */
-#define IPC_SET                1               /* Set `ipc_perm' options.  */
-#define IPC_STAT       2               /* Get `ipc_perm' options.  */
-#ifdef __USE_GNU
-# define IPC_INFO      3               /* See ipcs.  */
-#endif
-
-/* Special key values.  */
-#define IPC_PRIVATE    ((__key_t) 0)   /* Private key.  */
-
-
 /* Data structure used to pass permission information to IPC operations.  */
 struct ipc_perm
   {
@@ -47,14 +28,8 @@ struct ipc_perm
     __gid_t gid;                       /* Owner's group ID.  */
     __uid_t cuid;                      /* Creator's user ID.  */
     __gid_t cgid;                      /* Creator's group ID.  */
-#if __WORDSIZE == 32
-    unsigned short int __pad1;
-    unsigned short int mode;           /* Read/write permission.  */
-    unsigned short int __pad2;
-#else
     __mode_t mode;                     /* Read/write permission.  */
     unsigned short int __pad1;
-#endif
     unsigned short int __seq;          /* Sequence number.  */
     __extension__ unsigned long long int __glibc_reserved1;
     __extension__ unsigned long long int __glibc_reserved2;